Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 432956
Collapse All | Expand All

(-)a/bundles/org.eclipse.orion.client.javascript/web/esprima/esprima.js (-2738 / +3115 lines)
Lines 1-12 Link Here
1
/*
1
/*
2
2
  Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
3
  Original copyright is below.  This is version git tag: 310927be9f.
3
  Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
4
  Further modifications:
4
  Copyright (C) 2013 Mathias Bynens <mathias@qiwi.be>
5
  Author: Andy Clement (VMware) - recovery support
6
7
8
  Original copyright:
9
10
  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
5
  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
11
  Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
6
  Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
12
  Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
7
  Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
Lines 37-67 Link Here
37
*/
32
*/
38
33
39
/*jslint bitwise:true plusplus:true */
34
/*jslint bitwise:true plusplus:true */
40
/*global esprima:true, exports:true,
35
/*global esprima:true, define:true, exports:true, window: true,
41
throwError: true, createLiteral: true, generateStatement: true,
36
createLocationMarker: true,
37
throwError: true, generateStatement: true, peek: true,
42
parseAssignmentExpression: true, parseBlock: true, 
38
parseAssignmentExpression: true, parseBlock: true, 
43
expectCloseBracketWrapThrow: true, parseExpression: true,
39
expectConditionCloseBracketWrapThrow: true, parseExpression: true,
44
parseFunctionDeclaration: true, parseFunctionExpression: true,
40
parseFunctionDeclaration: true, parseFunctionExpression: true,
45
parseFunctionSourceElements: true, parseVariableIdentifier: true,
41
parseFunctionSourceElements: true, parseVariableIdentifier: true,
46
parseLeftHandSideExpression: true,
42
parseLeftHandSideExpression: true,
43
parseUnaryExpression: true,
47
parseStatement: true, parseSourceElement: true */
44
parseStatement: true, parseSourceElement: true */
48
45
49
(function (exports) {
46
(function (root, factory) {
47
    'use strict';
48
49
    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
50
    // Rhino, and plain browser loading.
51
    if (typeof define === 'function' && define.amd) {
52
        define(['exports'], factory);
53
    } else if (typeof exports !== 'undefined') {
54
        factory(exports);
55
    } else {
56
        factory((root.esprima = {}));
57
    }
58
}(this, function (exports) {
50
    'use strict';
59
    'use strict';
51
60
52
    var Token,
61
    var Token,
53
        TokenName,
62
        TokenName,
63
        FnExprTokens,
54
        Syntax,
64
        Syntax,
55
        PropertyKind,
65
        PropertyKind,
56
        Messages,
66
        Messages,
57
        Regex,
67
        Regex,
68
        SyntaxTreeDelegate,
58
        source,
69
        source,
59
        strict,
70
        strict,
60
        index,
71
        index,
61
        lineNumber,
72
        lineNumber,
62
        lineStart,
73
        lineStart,
63
        length,
74
        length,
64
        buffer,
75
        delegate,
76
        lookahead,
65
        state,
77
        state,
66
        extra;
78
        extra;
67
79
Lines 73-79 Link Here
73
        NullLiteral: 5,
85
        NullLiteral: 5,
74
        NumericLiteral: 6,
86
        NumericLiteral: 6,
75
        Punctuator: 7,
87
        Punctuator: 7,
76
        StringLiteral: 8
88
        StringLiteral: 8,
89
        RegularExpression: 9
77
    };
90
    };
78
91
79
    TokenName = {};
92
    TokenName = {};
Lines 85-90 Link Here
85
    TokenName[Token.NumericLiteral] = 'Numeric';
98
    TokenName[Token.NumericLiteral] = 'Numeric';
86
    TokenName[Token.Punctuator] = 'Punctuator';
99
    TokenName[Token.Punctuator] = 'Punctuator';
87
    TokenName[Token.StringLiteral] = 'String';
100
    TokenName[Token.StringLiteral] = 'String';
101
    TokenName[Token.RegularExpression] = 'RegularExpression';
102
103
    // A function following one of those tokens is an expression.
104
    FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
105
                    'return', 'case', 'delete', 'throw', 'void',
106
                    // assignment operators
107
                    '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
108
                    '&=', '|=', '^=', ',',
109
                    // binary/unary operators
110
                    '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
111
                    '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
112
                    '<=', '<', '>', '!=', '!=='];
88
113
89
    Syntax = {
114
    Syntax = {
90
        AssignmentExpression: 'AssignmentExpression',
115
        AssignmentExpression: 'AssignmentExpression',
Lines 148-153 Link Here
148
        UnterminatedRegExp:  'Invalid regular expression: missing /',
173
        UnterminatedRegExp:  'Invalid regular expression: missing /',
149
        InvalidLHSInAssignment:  'Invalid left-hand side in assignment',
174
        InvalidLHSInAssignment:  'Invalid left-hand side in assignment',
150
        InvalidLHSInForIn:  'Invalid left-hand side in for-in',
175
        InvalidLHSInForIn:  'Invalid left-hand side in for-in',
176
        MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
151
        NoCatchOrFinally:  'Missing catch or finally after try',
177
        NoCatchOrFinally:  'Missing catch or finally after try',
152
        UnknownLabel: 'Undefined label \'%0\'',
178
        UnknownLabel: 'Undefined label \'%0\'',
153
        Redeclaration: '%0 \'%1\' has already been declared',
179
        Redeclaration: '%0 \'%1\' has already been declared',
Lines 168-180 Link Here
168
        StrictLHSAssignment:  'Assignment to eval or arguments is not allowed in strict mode',
194
        StrictLHSAssignment:  'Assignment to eval or arguments is not allowed in strict mode',
169
        StrictLHSPostfix:  'Postfix increment/decrement may not have eval or arguments operand in strict mode',
195
        StrictLHSPostfix:  'Postfix increment/decrement may not have eval or arguments operand in strict mode',
170
        StrictLHSPrefix:  'Prefix increment/decrement may not have eval or arguments operand in strict mode',
196
        StrictLHSPrefix:  'Prefix increment/decrement may not have eval or arguments operand in strict mode',
171
        StrictReservedWord:  'Use of future reserved word in strict mode'
197
        StrictReservedWord:  'Use of future reserved word in strict mode',
198
        //mrennie https://bugs.eclipse.org/bugs/show_bug.cgi?id=432956
199
        MissingToken: 'Missing expected \'%0\''
172
    };
200
    };
173
201
174
    // See also tools/generate-unicode-regex.py.
202
    // See also tools/generate-unicode-regex.py.
175
    Regex = {
203
    Regex = {
176
        NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\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\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\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-\u0c33\u0c35-\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-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\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\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\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\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\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-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\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]'),
204
        NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\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\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\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-\u0C33\u0C35-\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-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\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\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\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-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\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]'),
177
        NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\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\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\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\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\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\u0d02\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\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\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\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-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\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\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\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\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\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-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\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-\ufe26\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]')
205
        NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\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\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\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\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\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\u0D02\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\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\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\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-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\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\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\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-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\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-\uFE26\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]')
178
    };
206
    };
179
207
180
    // Ensure the condition is true, otherwise throw an error.
208
    // Ensure the condition is true, otherwise throw an error.
Lines 188-205 Link Here
188
        }
216
        }
189
    }
217
    }
190
218
191
    function sliceSource(from, to) {
192
        return source.slice(from, to);
193
    }
194
195
    if (typeof 'esprima'[0] === 'undefined') {
196
        sliceSource = function sliceArraySource(from, to) {
197
            return source.slice(from, to).join('');
198
        };
199
    }
200
201
    function isDecimalDigit(ch) {
219
    function isDecimalDigit(ch) {
202
        return '0123456789'.indexOf(ch) >= 0;
220
        return (ch >= 48 && ch <= 57);   // 0..9
203
    }
221
    }
204
222
205
    function isHexDigit(ch) {
223
    function isHexDigit(ch) {
Lines 214-252 Link Here
214
    // 7.2 White Space
232
    // 7.2 White Space
215
233
216
    function isWhiteSpace(ch) {
234
    function isWhiteSpace(ch) {
217
        return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') ||
235
        return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
218
            (ch === '\u000C') || (ch === '\u00A0') ||
236
            (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
219
            (ch.charCodeAt(0) >= 0x1680 &&
220
             '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0);
221
    }
237
    }
222
238
223
    // 7.3 Line Terminators
239
    // 7.3 Line Terminators
224
240
225
    function isLineTerminator(ch) {
241
    function isLineTerminator(ch) {
226
        return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');
242
        return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
227
    }
243
    }
228
244
229
    // 7.6 Identifier Names and Identifiers
245
    // 7.6 Identifier Names and Identifiers
230
246
231
    function isIdentifierStart(ch) {
247
    function isIdentifierStart(ch) {
232
        return (ch === '$') || (ch === '_') || (ch === '\\') ||
248
        return (ch === 36) || (ch === 95) ||  // $ (dollar) and _ (underscore)
233
            (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
249
            (ch >= 65 && ch <= 90) ||         // A..Z
234
            ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierStart.test(ch));
250
            (ch >= 97 && ch <= 122) ||        // a..z
251
            (ch === 92) ||                    // \ (backslash)
252
            ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
235
    }
253
    }
236
254
237
    function isIdentifierPart(ch) {
255
    function isIdentifierPart(ch) {
238
        return (ch === '$') || (ch === '_') || (ch === '\\') ||
256
        return (ch === 36) || (ch === 95) ||  // $ (dollar) and _ (underscore)
239
            (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
257
            (ch >= 65 && ch <= 90) ||         // A..Z
240
            ((ch >= '0') && (ch <= '9')) ||
258
            (ch >= 97 && ch <= 122) ||        // a..z
241
            ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierPart.test(ch));
259
            (ch >= 48 && ch <= 57) ||         // 0..9
260
            (ch === 92) ||                    // \ (backslash)
261
            ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
242
    }
262
    }
243
263
244
    // 7.6.1.2 Future Reserved Words
264
    // 7.6.1.2 Future Reserved Words
245
265
246
    function isFutureReservedWord(id) {
266
    function isFutureReservedWord(id) {
247
        switch (id) {
267
        switch (id) {
248
249
        // Future reserved words.
250
        case 'class':
268
        case 'class':
251
        case 'enum':
269
        case 'enum':
252
        case 'export':
270
        case 'export':
Lines 254-268 Link Here
254
        case 'import':
272
        case 'import':
255
        case 'super':
273
        case 'super':
256
            return true;
274
            return true;
275
        default:
276
            return false;
257
        }
277
        }
258
259
        return false;
260
    }
278
    }
261
279
262
    function isStrictModeReservedWord(id) {
280
    function isStrictModeReservedWord(id) {
263
        switch (id) {
281
        switch (id) {
264
265
        // Strict Mode reserved words.
266
        case 'implements':
282
        case 'implements':
267
        case 'interface':
283
        case 'interface':
268
        case 'package':
284
        case 'package':
Lines 273-281 Link Here
273
        case 'yield':
289
        case 'yield':
274
        case 'let':
290
        case 'let':
275
            return true;
291
            return true;
292
        default:
293
            return false;
276
        }
294
        }
277
278
        return false;
279
    }
295
    }
280
296
281
    function isRestrictedWord(id) {
297
    function isRestrictedWord(id) {
Lines 285-451 Link Here
285
    // 7.6.1.1 Keywords
301
    // 7.6.1.1 Keywords
286
302
287
    function isKeyword(id) {
303
    function isKeyword(id) {
288
        var keyword = false;
289
        switch (id.length) {
290
        case 2:
291
            keyword = (id === 'if') || (id === 'in') || (id === 'do');
292
            break;
293
        case 3:
294
            keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');
295
            break;
296
        case 4:
297
            keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with');
298
            break;
299
        case 5:
300
            keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw');
301
            break;
302
        case 6:
303
            keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch');
304
            break;
305
        case 7:
306
            keyword = (id === 'default') || (id === 'finally');
307
            break;
308
        case 8:
309
            keyword = (id === 'function') || (id === 'continue') || (id === 'debugger');
310
            break;
311
        case 10:
312
            keyword = (id === 'instanceof');
313
            break;
314
        }
315
316
        if (keyword) {
317
            return true;
318
        }
319
320
        switch (id) {
321
        // Future reserved words.
322
        // 'const' is specialized as Keyword in V8.
323
        case 'const':
324
            return true;
325
326
        // For compatiblity to SpiderMonkey and ES.next
327
        case 'yield':
328
        case 'let':
329
            return true;
330
        }
331
332
        if (strict && isStrictModeReservedWord(id)) {
304
        if (strict && isStrictModeReservedWord(id)) {
333
            return true;
305
            return true;
334
        }
306
        }
335
307
336
        return isFutureReservedWord(id);
308
        // 'const' is specialized as Keyword in V8.
337
    }
309
        // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.
310
        // Some others are from future reserved words.
338
311
339
    // Return the next character and move forward.
312
        switch (id.length) {
340
313
        case 2:
341
    function nextChar() {
314
            return (id === 'if') || (id === 'in') || (id === 'do');
342
        return source[index++];
315
        case 3:
343
    }
316
            return (id === 'var') || (id === 'for') || (id === 'new') ||
344
    
317
                (id === 'try') || (id === 'let');
345
    
318
        case 4:
346
    function isNewlineOrSemicolon(ch) {
319
            return (id === 'this') || (id === 'else') || (id === 'case') ||
347
      return ch===';' || ch==='\n';
320
                (id === 'void') || (id === 'with') || (id === 'enum');
348
    }
321
        case 5:
349
    
322
            return (id === 'while') || (id === 'break') || (id === 'catch') ||
350
    /**
323
                (id === 'throw') || (id === 'const') || (id === 'yield') ||
351
     * rewind the lex position to the most recent newline or semicolon.  If that turns out
324
                (id === 'class') || (id === 'super');
352
     * to be the same position as the most recent parsing of a statement was attempted at, 
325
        case 6:
353
     * don't rewind (because it will fail in the same way).  If it turns out to be the same
326
            return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
354
     * position as where we last rewound to, don't do it.  Clears the buffer and sets the
327
                (id === 'switch') || (id === 'export') || (id === 'import');
355
     * index in order to continue lexing from the new position.
328
        case 7:
356
     */
329
            return (id === 'default') || (id === 'finally') || (id === 'extends');
357
    function rewind() {
330
        case 8:
358
        var idx = index;
331
            return (id === 'function') || (id === 'continue') || (id === 'debugger');
359
        while (idx>0 && !isNewlineOrSemicolon(source[idx])) {
332
        case 10:
360
            idx--;
333
            return (id === 'instanceof');
361
        }
334
        default:
362
        if (idx<=extra.statementStart) {
335
            return false;
363
            return;
364
        }
365
        var doRewind = false;
366
        if (extra.lastRewindLocation) {
367
            doRewind = true;
368
        } else {
369
            var v = extra.lastRewindLocation;
370
            if (v!==idx) {
371
              doRewind=true;
372
            }
373
        }	        
374
        if (doRewind) {
375
	        index = idx;
376
	        buffer = null;
377
	        extra.lastRewindLocation = index;
378
        }
336
        }
379
    }
337
    }
380
338
381
    // 7.4 Comments
339
    // 7.4 Comments
382
340
383
    function skipComment() {
341
    function addComment(type, value, start, end, loc) {
384
        var ch, blockComment, lineComment;
342
        var comment, attacher;
385
343
386
        blockComment = false;
344
        assert(typeof start === 'number', 'Comment must have valid position');
387
        lineComment = false;
345
346
        // Because the way the actual token is scanned, often the comments
347
        // (if any) are skipped twice during the lexical analysis.
348
        // Thus, we need to skip adding a comment if the comment array already
349
        // handled it.
350
        if (state.lastCommentStart >= start) {
351
            return;
352
        }
353
        state.lastCommentStart = start;
354
355
        comment = {
356
            type: type,
357
            value: value
358
        };
359
        if (extra.range) {
360
            comment.range = [start, end];
361
        }
362
        if (extra.loc) {
363
            comment.loc = loc;
364
        }
365
        extra.comments.push(comment);
366
367
        if (extra.attachComment) {
368
            attacher = {
369
                comment: comment,
370
                leading: null,
371
                trailing: null,
372
                range: [start, end]
373
            };
374
            extra.pendingComments.push(attacher);
375
        }
376
    }
377
378
    function skipSingleLineComment() {
379
        var start, loc, ch, comment;
380
381
        start = index - 2;
382
        loc = {
383
            start: {
384
                line: lineNumber,
385
                column: index - lineStart - 2
386
            }
387
        };
388
388
389
        while (index < length) {
389
        while (index < length) {
390
            ch = source[index];
390
            ch = source.charCodeAt(index);
391
391
            ++index;
392
            if (lineComment) {
392
            if (isLineTerminator(ch)) {
393
                ch = nextChar();
393
                if (extra.comments) {
394
                if (isLineTerminator(ch)) {
394
                    comment = source.slice(start + 2, index - 1);
395
                    lineComment = false;
395
                    loc.end = {
396
                    if (ch === '\r' && source[index] === '\n') {
396
                        line: lineNumber,
397
                        ++index;
397
                        column: index - lineStart - 1
398
                    }
398
                    };
399
                    ++lineNumber;
399
                    addComment('Line', comment, start, index - 1, loc);
400
                    lineStart = index;
401
                }
400
                }
402
            } else if (blockComment) {
401
                if (ch === 13 && source.charCodeAt(index) === 10) {
403
                if (isLineTerminator(ch)) {
404
                    if (ch === '\r' && source[index + 1] === '\n') {
405
                        ++index;
406
                    }
407
                    ++lineNumber;
408
                    ++index;
409
                    lineStart = index;
410
                    if (index >= length) {
411
                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
412
                    }
413
                } else {
414
                    ch = nextChar();
415
                    if (index >= length) {
416
                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
417
                    }
418
                    if (ch === '*') {
419
                        ch = source[index];
420
                        if (ch === '/') {
421
                            ++index;
422
                            blockComment = false;
423
                        }
424
                    }
425
                }
426
            } else if (ch === '/') {
427
                ch = source[index + 1];
428
                if (ch === '/') {
429
                    index += 2;
430
                    lineComment = true;
431
                } else if (ch === '*') {
432
                    index += 2;
433
                    blockComment = true;
434
                    if (index >= length) {
435
                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
436
                    }
437
                } else {
438
                    break;
439
                }
440
            } else if (isWhiteSpace(ch)) {
441
                ++index;
442
            } else if (isLineTerminator(ch)) {
443
                ++index;
444
                if (ch ===  '\r' && source[index] === '\n') {
445
                    ++index;
402
                    ++index;
446
                }
403
                }
447
                ++lineNumber;
404
                ++lineNumber;
448
                lineStart = index;
405
                lineStart = index;
406
                return;
407
            }
408
        }
409
410
        if (extra.comments) {
411
            comment = source.slice(start + 2, index);
412
            loc.end = {
413
                line: lineNumber,
414
                column: index - lineStart
415
            };
416
            addComment('Line', comment, start, index, loc);
417
        }
418
    }
419
420
    function skipMultiLineComment() {
421
        var start, loc, ch, comment;
422
423
        if (extra.comments) {
424
            start = index - 2;
425
            loc = {
426
                start: {
427
                    line: lineNumber,
428
                    column: index - lineStart - 2
429
                }
430
            };
431
        }
432
433
        while (index < length) {
434
            ch = source.charCodeAt(index);
435
            if (isLineTerminator(ch)) {
436
                if (ch === 13 && source.charCodeAt(index + 1) === 10) {
437
                    ++index;
438
                }
439
                ++lineNumber;
440
                ++index;
441
                lineStart = index;
442
                if (index >= length) {
443
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
444
                }
445
            } else if (ch === 42) {
446
                // Block comment ends with '*/' (char #42, char #47).
447
                if (source.charCodeAt(index + 1) === 47) {
448
                    ++index;
449
                    ++index;
450
                    if (extra.comments) {
451
                        comment = source.slice(start + 2, index - 2);
452
                        loc.end = {
453
                            line: lineNumber,
454
                            column: index - lineStart
455
                        };
456
                        addComment('Block', comment, start, index, loc);
457
                    }
458
                    return;
459
                }
460
                ++index;
461
            } else {
462
                ++index;
463
            }
464
        }
465
466
        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
467
    }
468
469
    function skipComment() {
470
        var ch, start;
471
472
        start = (index === 0);
473
        while (index < length) {
474
            ch = source.charCodeAt(index);
475
476
            if (isWhiteSpace(ch)) {
477
                ++index;
478
            } else if (isLineTerminator(ch)) {
479
                ++index;
480
                if (ch === 13 && source.charCodeAt(index) === 10) {
481
                    ++index;
482
                }
483
                ++lineNumber;
484
                lineStart = index;
485
                start = true;
486
            } else if (ch === 47) { // 47 is '/'
487
                ch = source.charCodeAt(index + 1);
488
                if (ch === 47) {
489
                    ++index;
490
                    ++index;
491
                    skipSingleLineComment();
492
                    start = true;
493
                } else if (ch === 42) {  // 42 is '*'
494
                    ++index;
495
                    ++index;
496
                    skipMultiLineComment();
497
                } else {
498
                    break;
499
                }
500
            } else if (start && ch === 45) { // 45 is '-'
501
                // 62 is '>'
502
                if ((source.charCodeAt(index + 1) === 45) && (source.charCodeAt(index + 2) === 62)) {
503
                    // '-->' is a single-line comment
504
                    index += 3;
505
                    skipSingleLineComment();
506
                } else {
507
                    break;
508
                }
509
            } else if (ch === 60) { // 60 is '<'
510
                if (source.slice(index + 1, index + 4) === '!--') {
511
                    ++index; // `<`
512
                    ++index; // `!`
513
                    ++index; // `-`
514
                    ++index; // `-`
515
                    skipSingleLineComment();
516
                } else {
517
                    break;
518
                }
449
            } else {
519
            } else {
450
                break;
520
                break;
451
            }
521
            }
Lines 458-464 Link Here
458
        len = (prefix === 'u') ? 4 : 2;
528
        len = (prefix === 'u') ? 4 : 2;
459
        for (i = 0; i < len; ++i) {
529
        for (i = 0; i < len; ++i) {
460
            if (index < length && isHexDigit(source[index])) {
530
            if (index < length && isHexDigit(source[index])) {
461
                ch = nextChar();
531
                ch = source[index++];
462
                code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
532
                code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
463
            } else {
533
            } else {
464
                return '';
534
                return '';
Lines 467-577 Link Here
467
        return String.fromCharCode(code);
537
        return String.fromCharCode(code);
468
    }
538
    }
469
539
470
    function scanIdentifier() {
540
    function getEscapedIdentifier() {
471
        var ch, start, id, restore;
541
        var ch, id;
472
542
473
        ch = source[index];
543
        ch = source.charCodeAt(index++);
474
        if (!isIdentifierStart(ch)) {
544
        id = String.fromCharCode(ch);
475
            return;
476
        }
477
545
478
        start = index;
546
        // '\u' (char #92, char #117) denotes an escaped character.
479
        if (ch === '\\') {
547
        if (ch === 92) {
480
            ++index;
548
            if (source.charCodeAt(index) !== 117) {
481
            if (source[index] !== 'u') {
549
                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
482
                return;
483
            }
550
            }
484
            ++index;
551
            ++index;
485
            restore = index;
486
            ch = scanHexEscape('u');
552
            ch = scanHexEscape('u');
487
            if (ch) {
553
            if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
488
                if (ch === '\\' || !isIdentifierStart(ch)) {
554
                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
489
                    return;
490
                }
491
                id = ch;
492
            } else {
493
                index = restore;
494
                id = 'u';
495
            }
555
            }
496
        } else {
556
            id = ch;
497
            id = nextChar();
498
        }
557
        }
499
558
500
        while (index < length) {
559
        while (index < length) {
501
            ch = source[index];
560
            ch = source.charCodeAt(index);
502
            if (!isIdentifierPart(ch)) {
561
            if (!isIdentifierPart(ch)) {
503
                break;
562
                break;
504
            }
563
            }
505
            if (ch === '\\') {
564
            ++index;
506
                ++index;
565
            id += String.fromCharCode(ch);
507
                if (source[index] !== 'u') {
566
508
                    return;
567
            // '\u' (char #92, char #117) denotes an escaped character.
568
            if (ch === 92) {
569
                id = id.substr(0, id.length - 1);
570
                if (source.charCodeAt(index) !== 117) {
571
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
509
                }
572
                }
510
                ++index;
573
                ++index;
511
                restore = index;
512
                ch = scanHexEscape('u');
574
                ch = scanHexEscape('u');
513
                if (ch) {
575
                if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
514
                    if (ch === '\\' || !isIdentifierPart(ch)) {
576
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
515
                        return;
516
                    }
517
                    id += ch;
518
                } else {
519
                    index = restore;
520
                    id += 'u';
521
                }
577
                }
522
            } else {
578
                id += ch;
523
                id += nextChar();
524
            }
579
            }
525
        }
580
        }
581
582
        return id;
583
    }
584
585
    function getIdentifier() {
586
        var start, ch;
587
588
        start = index++;
589
        while (index < length) {
590
            ch = source.charCodeAt(index);
591
            if (ch === 92) {
592
                // Blackslash (char #92) marks Unicode escape sequence.
593
                index = start;
594
                return getEscapedIdentifier();
595
            }
596
            if (isIdentifierPart(ch)) {
597
                ++index;
598
            } else {
599
                break;
600
            }
601
        }
602
603
        return source.slice(start, index);
604
    }
605
606
    function scanIdentifier() {
607
        var start, id, type;
608
609
        start = index;
610
611
        // Backslash (char #92) starts an escaped character.
612
        id = (source.charCodeAt(index) === 92) ? getEscapedIdentifier() : getIdentifier();
526
613
527
        // There is no keyword or literal with only one character.
614
        // There is no keyword or literal with only one character.
528
        // Thus, it must be an identifier.
615
        // Thus, it must be an identifier.
529
        if (id.length === 1) {
616
        if (id.length === 1) {
530
            return {
617
            type = Token.Identifier;
531
                type: Token.Identifier,
618
        } else if (isKeyword(id)) {
532
                value: id,
619
            type = Token.Keyword;
533
                lineNumber: lineNumber,
620
        } else if (id === 'null') {
534
                lineStart: lineStart,
621
            type = Token.NullLiteral;
535
                range: [start, index]
622
        } else if (id === 'true' || id === 'false') {
536
            };
623
            type = Token.BooleanLiteral;
537
        }
624
        } else {
538
625
            type = Token.Identifier;
539
        if (isKeyword(id)) {
540
            return {
541
                type: Token.Keyword,
542
                value: id,
543
                lineNumber: lineNumber,
544
                lineStart: lineStart,
545
                range: [start, index]
546
            };
547
        }
548
549
        // 7.8.1 Null Literals
550
551
        if (id === 'null') {
552
            return {
553
                type: Token.NullLiteral,
554
                value: id,
555
                lineNumber: lineNumber,
556
                lineStart: lineStart,
557
                range: [start, index]
558
            };
559
        }
560
561
        // 7.8.2 Boolean Literals
562
563
        if (id === 'true' || id === 'false') {
564
            return {
565
                type: Token.BooleanLiteral,
566
                value: id,
567
                lineNumber: lineNumber,
568
                lineStart: lineStart,
569
                range: [start, index]
570
            };
571
        }
626
        }
572
627
573
        return {
628
        return {
574
            type: Token.Identifier,
629
            type: type,
575
            value: id,
630
            value: id,
576
            lineNumber: lineNumber,
631
            lineNumber: lineNumber,
577
            lineStart: lineStart,
632
            lineStart: lineStart,
Lines 579-633 Link Here
579
        };
634
        };
580
    }
635
    }
581
636
637
582
    // 7.7 Punctuators
638
    // 7.7 Punctuators
583
639
584
    function scanPunctuator() {
640
    function scanPunctuator() {
585
        var start = index,
641
        var start = index,
642
            code = source.charCodeAt(index),
643
            code2,
586
            ch1 = source[index],
644
            ch1 = source[index],
587
            ch2,
645
            ch2,
588
            ch3,
646
            ch3,
589
            ch4;
647
            ch4;
590
648
649
        switch (code) {
650
591
        // Check for most common single-character punctuators.
651
        // Check for most common single-character punctuators.
592
652
        case 46:   // . dot
593
        if (ch1 === ';' || ch1 === '{' || ch1 === '}') {
653
        case 40:   // ( open bracket
654
        case 41:   // ) close bracket
655
        case 59:   // ; semicolon
656
        case 44:   // , comma
657
        case 123:  // { open curly brace
658
        case 125:  // } close curly brace
659
        case 91:   // [
660
        case 93:   // ]
661
        case 58:   // :
662
        case 63:   // ?
663
        case 126:  // ~
594
            ++index;
664
            ++index;
665
            if (extra.tokenize) {
666
                if (code === 40) {
667
                    extra.openParenToken = extra.tokens.length;
668
                } else if (code === 123) {
669
                    extra.openCurlyToken = extra.tokens.length;
670
                }
671
            }
595
            return {
672
            return {
596
                type: Token.Punctuator,
673
                type: Token.Punctuator,
597
                value: ch1,
674
                value: String.fromCharCode(code),
598
                lineNumber: lineNumber,
675
                lineNumber: lineNumber,
599
                lineStart: lineStart,
676
                lineStart: lineStart,
600
                range: [start, index]
677
                range: [start, index]
601
            };
678
            };
602
        }
603
679
604
        if (ch1 === ',' || ch1 === '(' || ch1 === ')') {
680
        default:
605
            ++index;
681
            code2 = source.charCodeAt(index + 1);
606
            return {
607
                type: Token.Punctuator,
608
                value: ch1,
609
                lineNumber: lineNumber,
610
                lineStart: lineStart,
611
                range: [start, index]
612
            };
613
        }
614
682
615
        // Dot (.) can also start a floating-point number, hence the need
683
            // '=' (char #61) marks an assignment or comparison operator.
616
        // to check the next character.
684
            if (code2 === 61) {
685
                switch (code) {
686
                case 37:  // %
687
                case 38:  // &
688
                case 42:  // *:
689
                case 43:  // +
690
                case 45:  // -
691
                case 47:  // /
692
                case 60:  // <
693
                case 62:  // >
694
                case 94:  // ^
695
                case 124: // |
696
                    index += 2;
697
                    return {
698
                        type: Token.Punctuator,
699
                        value: String.fromCharCode(code) + String.fromCharCode(code2),
700
                        lineNumber: lineNumber,
701
                        lineStart: lineStart,
702
                        range: [start, index]
703
                    };
617
704
618
        ch2 = source[index + 1];
705
                case 33: // !
619
        if (ch1 === '.' && !isDecimalDigit(ch2)) {
706
                case 61: // =
620
            return {
707
                    index += 2;
621
                type: Token.Punctuator,
708
622
                value: nextChar(),
709
                    // !== and ===
623
                lineNumber: lineNumber,
710
                    if (source.charCodeAt(index) === 61) {
624
                lineStart: lineStart,
711
                        ++index;
625
                range: [start, index]
712
                    }
626
            };
713
                    return {
714
                        type: Token.Punctuator,
715
                        value: source.slice(start, index),
716
                        lineNumber: lineNumber,
717
                        lineStart: lineStart,
718
                        range: [start, index]
719
                    };
720
                default:
721
                    break;
722
                }
723
            }
724
            break;
627
        }
725
        }
628
726
629
        // Peek more characters.
727
        // Peek more characters.
630
728
729
        ch2 = source[index + 1];
631
        ch3 = source[index + 2];
730
        ch3 = source[index + 2];
632
        ch4 = source[index + 3];
731
        ch4 = source[index + 3];
633
732
Lines 647-674 Link Here
647
        }
746
        }
648
747
649
        // 3-character punctuators: === !== >>> <<= >>=
748
        // 3-character punctuators: === !== >>> <<= >>=
650
651
        if (ch1 === '=' && ch2 === '=' && ch3 === '=') {
652
            index += 3;
653
            return {
654
                type: Token.Punctuator,
655
                value: '===',
656
                lineNumber: lineNumber,
657
                lineStart: lineStart,
658
                range: [start, index]
659
            };
660
        }
661
662
        if (ch1 === '!' && ch2 === '=' && ch3 === '=') {
663
            index += 3;
664
            return {
665
                type: Token.Punctuator,
666
                value: '!==',
667
                lineNumber: lineNumber,
668
                lineStart: lineStart,
669
                range: [start, index]
670
            };
671
        }
672
749
673
        if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
750
        if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
674
            index += 3;
751
            index += 3;
Lines 703-880 Link Here
703
            };
780
            };
704
        }
781
        }
705
782
706
        // 2-character punctuators: <= >= == != ++ -- << >> && ||
783
        // Other 2-character punctuators: ++ -- << >> && ||
707
        // += -= *= %= &= |= ^= /=
708
709
        if (ch2 === '=') {
710
            if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
711
                index += 2;
712
                return {
713
                    type: Token.Punctuator,
714
                    value: ch1 + ch2,
715
                    lineNumber: lineNumber,
716
                    lineStart: lineStart,
717
                    range: [start, index]
718
                };
719
            }
720
        }
721
784
722
        if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {
785
        if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {
723
            if ('+-<>&|'.indexOf(ch2) >= 0) {
786
            index += 2;
724
                index += 2;
725
                return {
726
                    type: Token.Punctuator,
727
                    value: ch1 + ch2,
728
                    lineNumber: lineNumber,
729
                    lineStart: lineStart,
730
                    range: [start, index]
731
                };
732
            }
733
        }
734
735
        // The remaining 1-character punctuators.
736
737
        if ('[]<>+-*%&|^!~?:=/'.indexOf(ch1) >= 0) {
738
            return {
787
            return {
739
                type: Token.Punctuator,
788
                type: Token.Punctuator,
740
                value: nextChar(),
789
                value: ch1 + ch2,
741
                lineNumber: lineNumber,
790
                lineNumber: lineNumber,
742
                lineStart: lineStart,
791
                lineStart: lineStart,
743
                range: [start, index]
792
                range: [start, index]
744
            };
793
            };
745
        }
794
        }
795
796
        if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
797
            ++index;
798
            return {
799
                type: Token.Punctuator,
800
                value: ch1,
801
                lineNumber: lineNumber,
802
                lineStart: lineStart,
803
                range: [start, index]
804
            };
805
        }
806
807
        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
746
    }
808
    }
747
809
748
    // 7.8.3 Numeric Literals
810
    // 7.8.3 Numeric Literals
811
812
    function scanHexLiteral(start) {
813
        var number = '';
814
815
        while (index < length) {
816
            if (!isHexDigit(source[index])) {
817
                break;
818
            }
819
            number += source[index++];
820
        }
821
822
        if (number.length === 0) {
823
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
824
        }
825
826
        if (isIdentifierStart(source.charCodeAt(index))) {
827
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
828
        }
829
830
        return {
831
            type: Token.NumericLiteral,
832
            value: parseInt('0x' + number, 16),
833
            lineNumber: lineNumber,
834
            lineStart: lineStart,
835
            range: [start, index]
836
        };
837
    }
838
839
    function scanOctalLiteral(start) {
840
        var number = '0' + source[index++];
841
        while (index < length) {
842
            if (!isOctalDigit(source[index])) {
843
                break;
844
            }
845
            number += source[index++];
846
        }
847
848
        if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
849
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
850
        }
851
852
        return {
853
            type: Token.NumericLiteral,
854
            value: parseInt(number, 8),
855
            octal: true,
856
            lineNumber: lineNumber,
857
            lineStart: lineStart,
858
            range: [start, index]
859
        };
860
    }
749
861
750
    function scanNumericLiteral() {
862
    function scanNumericLiteral() {
751
        var number, start, ch;
863
        var number, start, ch;
752
864
753
        ch = source[index];
865
        ch = source[index];
754
        assert(isDecimalDigit(ch) || (ch === '.'),
866
        assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
755
            'Numeric literal must start with a decimal digit or a decimal point');
867
            'Numeric literal must start with a decimal digit or a decimal point');
756
868
757
        start = index;
869
        start = index;
758
        number = '';
870
        number = '';
759
        if (ch !== '.') {
871
        if (ch !== '.') {
760
            number = nextChar();
872
            number = source[index++];
761
            ch = source[index];
873
            ch = source[index];
762
874
763
            // Hex number starts with '0x'.
875
            // Hex number starts with '0x'.
764
            // Octal number starts with '0'.
876
            // Octal number starts with '0'.
765
            if (number === '0') {
877
            if (number === '0') {
766
                if (ch === 'x' || ch === 'X') {
878
                if (ch === 'x' || ch === 'X') {
767
                    number += nextChar();
879
                    ++index;
768
                    while (index < length) {
880
                    return scanHexLiteral(start);
769
                        ch = source[index];
881
                }
770
                        if (!isHexDigit(ch)) {
882
                if (isOctalDigit(ch)) {
771
                            break;
883
                    return scanOctalLiteral(start);
772
                        }
773
                        number += nextChar();
774
                    }
775
776
                    if (number.length <= 2) {
777
                        // only 0x
778
                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
779
                    }
780
781
                    if (index < length) {
782
                        ch = source[index];
783
                        if (isIdentifierStart(ch)) {
784
                            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
785
                        }
786
                    }
787
                    return {
788
                        type: Token.NumericLiteral,
789
                        value: parseInt(number, 16),
790
                        lineNumber: lineNumber,
791
                        lineStart: lineStart,
792
                        range: [start, index]
793
                    };
794
                } else if (isOctalDigit(ch)) {
795
                    number += nextChar();
796
                    while (index < length) {
797
                        ch = source[index];
798
                        if (!isOctalDigit(ch)) {
799
                            break;
800
                        }
801
                        number += nextChar();
802
                    }
803
804
                    if (index < length) {
805
                        ch = source[index];
806
                        if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
807
                            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
808
                        }
809
                    }
810
                    return {
811
                        type: Token.NumericLiteral,
812
                        value: parseInt(number, 8),
813
                        octal: true,
814
                        lineNumber: lineNumber,
815
                        lineStart: lineStart,
816
                        range: [start, index]
817
                    };
818
                }
884
                }
819
885
820
                // decimal number starts with '0' such as '09' is illegal.
886
                // decimal number starts with '0' such as '09' is illegal.
821
                if (isDecimalDigit(ch)) {
887
                if (ch && isDecimalDigit(ch.charCodeAt(0))) {
822
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
888
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
823
                }
889
                }
824
            }
890
            }
825
891
826
            while (index < length) {
892
            while (isDecimalDigit(source.charCodeAt(index))) {
827
                ch = source[index];
893
                number += source[index++];
828
                if (!isDecimalDigit(ch)) {
829
                    break;
830
                }
831
                number += nextChar();
832
            }
894
            }
895
            ch = source[index];
833
        }
896
        }
834
897
835
        if (ch === '.') {
898
        if (ch === '.') {
836
            number += nextChar();
899
            number += source[index++];
837
            while (index < length) {
900
            while (isDecimalDigit(source.charCodeAt(index))) {
838
                ch = source[index];
901
                number += source[index++];
839
                if (!isDecimalDigit(ch)) {
840
                    break;
841
                }
842
                number += nextChar();
843
            }
902
            }
903
            ch = source[index];
844
        }
904
        }
845
905
846
        if (ch === 'e' || ch === 'E') {
906
        if (ch === 'e' || ch === 'E') {
847
            number += nextChar();
907
            number += source[index++];
848
908
849
            ch = source[index];
909
            ch = source[index];
850
            if (ch === '+' || ch === '-') {
910
            if (ch === '+' || ch === '-') {
851
                number += nextChar();
911
                number += source[index++];
852
            }
912
            }
853
913
            if (isDecimalDigit(source.charCodeAt(index))) {
854
            ch = source[index];
914
                while (isDecimalDigit(source.charCodeAt(index))) {
855
            if (isDecimalDigit(ch)) {
915
                    number += source[index++];
856
                number += nextChar();
857
                while (index < length) {
858
                    ch = source[index];
859
                    if (!isDecimalDigit(ch)) {
860
                        break;
861
                    }
862
                    number += nextChar();
863
                }
916
                }
864
            } else {
917
            } else {
865
                ch = 'character ' + ch;
866
                if (index >= length) {
867
                    ch = '<end>';
868
                }
869
                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
918
                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
870
            }
919
            }
871
        }
920
        }
872
921
873
        if (index < length) {
922
        if (isIdentifierStart(source.charCodeAt(index))) {
874
            ch = source[index];
923
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
875
            if (isIdentifierStart(ch)) {
876
                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
877
            }
878
        }
924
        }
879
925
880
        return {
926
        return {
Lines 899-912 Link Here
899
        ++index;
945
        ++index;
900
946
901
        while (index < length) {
947
        while (index < length) {
902
            ch = nextChar();
948
            ch = source[index++];
903
949
904
            if (ch === quote) {
950
            if (ch === quote) {
905
                quote = '';
951
                quote = '';
906
                break;
952
                break;
907
            } else if (ch === '\\') {
953
            } else if (ch === '\\') {
908
                ch = nextChar();
954
                ch = source[index++];
909
                if (!isLineTerminator(ch)) {
955
                if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
910
                    switch (ch) {
956
                    switch (ch) {
911
                    case 'n':
957
                    case 'n':
912
                        str += '\n';
958
                        str += '\n';
Lines 935-941 Link Here
935
                        str += '\f';
981
                        str += '\f';
936
                        break;
982
                        break;
937
                    case 'v':
983
                    case 'v':
938
                        str += '\v';
984
                        str += '\x0B';
939
                        break;
985
                        break;
940
986
941
                    default:
987
                    default:
Lines 949-962 Link Here
949
995
950
                            if (index < length && isOctalDigit(source[index])) {
996
                            if (index < length && isOctalDigit(source[index])) {
951
                                octal = true;
997
                                octal = true;
952
                                code = code * 8 + '01234567'.indexOf(nextChar());
998
                                code = code * 8 + '01234567'.indexOf(source[index++]);
953
999
954
                                // 3 digits are only allowed when string starts
1000
                                // 3 digits are only allowed when string starts
955
                                // with 0, 1, 2, 3
1001
                                // with 0, 1, 2, 3
956
                                if ('0123'.indexOf(ch) >= 0 &&
1002
                                if ('0123'.indexOf(ch) >= 0 &&
957
                                        index < length &&
1003
                                        index < length &&
958
                                        isOctalDigit(source[index])) {
1004
                                        isOctalDigit(source[index])) {
959
                                    code = code * 8 + '01234567'.indexOf(nextChar());
1005
                                    code = code * 8 + '01234567'.indexOf(source[index++]);
960
                                }
1006
                                }
961
                            }
1007
                            }
962
                            str += String.fromCharCode(code);
1008
                            str += String.fromCharCode(code);
Lines 971-977 Link Here
971
                        ++index;
1017
                        ++index;
972
                    }
1018
                    }
973
                }
1019
                }
974
            } else if (isLineTerminator(ch)) {
1020
            } else if (isLineTerminator(ch.charCodeAt(0))) {
975
                break;
1021
                break;
976
            } else {
1022
            } else {
977
                str += ch;
1023
                str += ch;
Lines 993-1037 Link Here
993
    }
1039
    }
994
1040
995
    function scanRegExp() {
1041
    function scanRegExp() {
996
        var str = '', ch, start, pattern, flags, value, classMarker = false, restore;
1042
        var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false;
997
1043
998
        buffer = null;
1044
        lookahead = null;
999
        skipComment();
1045
        skipComment();
1000
1046
1001
        start = index;
1047
        start = index;
1002
        ch = source[index];
1048
        ch = source[index];
1003
        assert(ch === '/', 'Regular expression literal must start with a slash');
1049
        assert(ch === '/', 'Regular expression literal must start with a slash');
1004
        str = nextChar();
1050
        str = source[index++];
1005
1051
1006
        while (index < length) {
1052
        while (index < length) {
1007
            ch = nextChar();
1053
            ch = source[index++];
1008
            str += ch;
1054
            str += ch;
1009
            if (classMarker) {
1055
            if (ch === '\\') {
1056
                ch = source[index++];
1057
                // ECMA-262 7.8.5
1058
                if (isLineTerminator(ch.charCodeAt(0))) {
1059
                    throwError({}, Messages.UnterminatedRegExp);
1060
                }
1061
                str += ch;
1062
            } else if (isLineTerminator(ch.charCodeAt(0))) {
1063
                throwError({}, Messages.UnterminatedRegExp);
1064
            } else if (classMarker) {
1010
                if (ch === ']') {
1065
                if (ch === ']') {
1011
                    classMarker = false;
1066
                    classMarker = false;
1012
                }
1067
                }
1013
            } else {
1068
            } else {
1014
                if (ch === '\\') {
1069
                if (ch === '/') {
1015
                    ch = nextChar();
1070
                    terminated = true;
1016
                    // ECMA-262 7.8.5
1017
                    if (isLineTerminator(ch)) {
1018
                        throwError({}, Messages.UnterminatedRegExp);
1019
                    }
1020
                    str += ch;
1021
                }
1022
                else if (ch === '/') {
1023
                    break;
1071
                    break;
1024
                }
1072
                } else if (ch === '[') {
1025
                else if (ch === '[') {
1026
                    classMarker = true;
1073
                    classMarker = true;
1027
                }
1028
                else if (isLineTerminator(ch)) {
1029
                    throwError({}, Messages.UnterminatedRegExp);
1030
                }
1074
                }
1031
            }
1075
            }
1032
        }
1076
        }
1033
1077
1034
        if (str.length === 1) {
1078
        if (!terminated) {
1035
            throwError({}, Messages.UnterminatedRegExp);
1079
            throwError({}, Messages.UnterminatedRegExp);
1036
        }
1080
        }
1037
1081
Lines 1041-1047 Link Here
1041
        flags = '';
1085
        flags = '';
1042
        while (index < length) {
1086
        while (index < length) {
1043
            ch = source[index];
1087
            ch = source[index];
1044
            if (!isIdentifierPart(ch)) {
1088
            if (!isIdentifierPart(ch.charCodeAt(0))) {
1045
                break;
1089
                break;
1046
            }
1090
            }
1047
1091
Lines 1054-1061 Link Here
1054
                    ch = scanHexEscape('u');
1098
                    ch = scanHexEscape('u');
1055
                    if (ch) {
1099
                    if (ch) {
1056
                        flags += ch;
1100
                        flags += ch;
1057
                        str += '\\u';
1101
                        for (str += '\\u'; restore < index; ++restore) {
1058
                        for (; restore < index; ++restore) {
1059
                            str += source[restore];
1102
                            str += source[restore];
1060
                        }
1103
                        }
1061
                    } else {
1104
                    } else {
Lines 1078-1088 Link Here
1078
            throwError({}, Messages.InvalidRegExp);
1121
            throwError({}, Messages.InvalidRegExp);
1079
        }
1122
        }
1080
1123
1124
1125
1126
        if (extra.tokenize) {
1127
            return {
1128
                type: Token.RegularExpression,
1129
                value: value,
1130
                lineNumber: lineNumber,
1131
                lineStart: lineStart,
1132
                range: [start, index]
1133
            };
1134
        }
1081
        return {
1135
        return {
1082
            literal: str,
1136
            literal: str,
1083
            value: value,
1137
            value: value,
1084
            range: [start, index]
1138
            range: [start, index]
1085
        };
1139
        };
1140
    }
1141
1142
    function collectRegex() {
1143
        var pos, loc, regex, token;
1144
1145
        skipComment();
1146
1147
        pos = index;
1148
        loc = {
1149
            start: {
1150
                line: lineNumber,
1151
                column: index - lineStart
1152
            }
1153
        };
1154
1155
        regex = scanRegExp();
1156
        loc.end = {
1157
            line: lineNumber,
1158
            column: index - lineStart
1159
        };
1160
1161
        if (!extra.tokenize) {
1162
            // Pop the previous token, which is likely '/' or '/='
1163
            if (extra.tokens.length > 0) {
1164
                token = extra.tokens[extra.tokens.length - 1];
1165
                if (token.range[0] === pos && token.type === 'Punctuator') {
1166
                    if (token.value === '/' || token.value === '/=') {
1167
                        extra.tokens.pop();
1168
                    }
1169
                }
1170
            }
1171
1172
            extra.tokens.push({
1173
                type: 'RegularExpression',
1174
                value: regex.literal,
1175
                range: [pos, index],
1176
                loc: loc
1177
            });
1178
        }
1179
1180
        return regex;
1086
    }
1181
    }
1087
1182
1088
    function isIdentifierName(token) {
1183
    function isIdentifierName(token) {
Lines 1092-1099 Link Here
1092
            token.type === Token.NullLiteral;
1187
            token.type === Token.NullLiteral;
1093
    }
1188
    }
1094
1189
1190
    function advanceSlash() {
1191
        var prevToken,
1192
            checkToken;
1193
        // Using the following algorithm:
1194
        // https://github.com/mozilla/sweet.js/wiki/design
1195
        prevToken = extra.tokens[extra.tokens.length - 1];
1196
        if (!prevToken) {
1197
            // Nothing before that: it cannot be a division.
1198
            return collectRegex();
1199
        }
1200
        if (prevToken.type === 'Punctuator') {
1201
            if (prevToken.value === ')') {
1202
                checkToken = extra.tokens[extra.openParenToken - 1];
1203
                if (checkToken &&
1204
                        checkToken.type === 'Keyword' &&
1205
                        (checkToken.value === 'if' ||
1206
                         checkToken.value === 'while' ||
1207
                         checkToken.value === 'for' ||
1208
                         checkToken.value === 'with')) {
1209
                    return collectRegex();
1210
                }
1211
                return scanPunctuator();
1212
            }
1213
            if (prevToken.value === '}') {
1214
                // Dividing a function by anything makes little sense,
1215
                // but we have to check for that.
1216
                if (extra.tokens[extra.openCurlyToken - 3] &&
1217
                        extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
1218
                    // Anonymous function.
1219
                    checkToken = extra.tokens[extra.openCurlyToken - 4];
1220
                    if (!checkToken) {
1221
                        return scanPunctuator();
1222
                    }
1223
                } else if (extra.tokens[extra.openCurlyToken - 4] &&
1224
                        extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
1225
                    // Named function.
1226
                    checkToken = extra.tokens[extra.openCurlyToken - 5];
1227
                    if (!checkToken) {
1228
                        return collectRegex();
1229
                    }
1230
                } else {
1231
                    return scanPunctuator();
1232
                }
1233
                // checkToken determines whether the function is
1234
                // a declaration or an expression.
1235
                if (FnExprTokens.indexOf(checkToken.value) >= 0) {
1236
                    // It is an expression.
1237
                    return scanPunctuator();
1238
                }
1239
                // It is a declaration.
1240
                return collectRegex();
1241
            }
1242
            return collectRegex();
1243
        }
1244
        if (prevToken.type === 'Keyword') {
1245
            return collectRegex();
1246
        }
1247
        return scanPunctuator();
1248
    }
1249
1095
    function advance() {
1250
    function advance() {
1096
        var ch, token;
1251
        var ch;
1097
1252
1098
        skipComment();
1253
        skipComment();
1099
1254
Lines 1106-1167 Link Here
1106
            };
1261
            };
1107
        }
1262
        }
1108
1263
1109
        token = scanPunctuator();
1264
        ch = source.charCodeAt(index);
1110
        if (typeof token !== 'undefined') {
1265
1111
            return token;
1266
        // Very common: ( and ) and ;
1267
        if (ch === 40 || ch === 41 || ch === 58) {
1268
            return scanPunctuator();
1112
        }
1269
        }
1113
1270
1114
        ch = source[index];
1271
        // String literal starts with single quote (#39) or double quote (#34).
1115
1272
        if (ch === 39 || ch === 34) {
1116
        if (ch === '\'' || ch === '"') {
1117
            return scanStringLiteral();
1273
            return scanStringLiteral();
1118
        }
1274
        }
1119
1275
1120
        if (ch === '.' || isDecimalDigit(ch)) {
1276
        if (isIdentifierStart(ch)) {
1277
            return scanIdentifier();
1278
        }
1279
1280
        // Dot (.) char #46 can also start a floating-point number, hence the need
1281
        // to check the next character.
1282
        if (ch === 46) {
1283
            if (isDecimalDigit(source.charCodeAt(index + 1))) {
1284
                return scanNumericLiteral();
1285
            }
1286
            return scanPunctuator();
1287
        }
1288
1289
        if (isDecimalDigit(ch)) {
1121
            return scanNumericLiteral();
1290
            return scanNumericLiteral();
1122
        }
1291
        }
1123
1292
1124
        token = scanIdentifier();
1293
        // Slash (/) char #47 can also start a regex.
1125
        if (typeof token !== 'undefined') {
1294
        if (extra.tokenize && ch === 47) {
1126
            return token;
1295
            return advanceSlash();
1127
        }
1296
        }
1128
1297
1129
        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
1298
        return scanPunctuator();
1299
    }
1300
1301
    function collectToken() {
1302
        var start, loc, token, range, value;
1303
1304
        skipComment();
1305
        start = index;
1306
        loc = {
1307
            start: {
1308
                line: lineNumber,
1309
                column: index - lineStart
1310
            }
1311
        };
1312
1313
        token = advance();
1314
        loc.end = {
1315
            line: lineNumber,
1316
            column: index - lineStart
1317
        };
1318
1319
        if (token.type !== Token.EOF) {
1320
            range = [token.range[0], token.range[1]];
1321
            value = source.slice(token.range[0], token.range[1]);
1322
            extra.tokens.push({
1323
                type: TokenName[token.type],
1324
                value: value,
1325
                range: range,
1326
                loc: loc
1327
            });
1328
        }
1329
1330
        return token;
1130
    }
1331
    }
1131
1332
1132
    function lex() {
1333
    function lex() {
1133
        var token;
1334
        var token;
1134
1335
1135
        if (buffer) {
1336
        token = lookahead;
1136
            index = buffer.range[1];
1337
        index = token.range[1];
1137
            lineNumber = buffer.lineNumber;
1338
        lineNumber = token.lineNumber;
1138
            lineStart = buffer.lineStart;
1339
        lineStart = token.lineStart;
1139
            token = buffer;
1140
            buffer = null;
1141
            return token;
1142
        }
1143
1340
1144
        buffer = null;
1341
        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
1145
        return advance();
1342
1343
        index = token.range[1];
1344
        lineNumber = token.lineNumber;
1345
        lineStart = token.lineStart;
1346
1347
        return token;
1146
    }
1348
    }
1147
1349
1148
    function lookahead() {
1350
    function peek() {
1149
        var pos, line, start;
1351
        var pos, line, start;
1150
1151
        if (buffer !== null) {
1152
            return buffer;
1153
        }
1154
1352
1155
        pos = index;
1353
        pos = index;
1156
        line = lineNumber;
1354
        line = lineNumber;
1157
        start = lineStart;
1355
        start = lineStart;
1158
        buffer = advance();
1356
        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
1159
        index = pos;
1357
        index = pos;
1160
        lineNumber = line;
1358
        lineNumber = line;
1161
        lineStart = start;
1359
        lineStart = start;
1162
1163
        return buffer;
1164
    }
1360
    }
1361
1362
    SyntaxTreeDelegate = {
1363
1364
        name: 'SyntaxTree',
1365
1366
        markStart: function () {
1367
            if (extra.loc) {
1368
                state.markerStack.push(index - lineStart);
1369
                state.markerStack.push(lineNumber);
1370
            }
1371
            if (extra.range) {
1372
                state.markerStack.push(index);
1373
            }
1374
        },
1375
1376
        processComment: function (node) {
1377
            var i, attacher, pos, len, candidate;
1378
1379
            if (typeof node.type === 'undefined' || node.type === Syntax.Program) {
1380
                return;
1381
            }
1382
1383
            // Check for possible additional trailing comments.
1384
            peek();
1385
1386
            for (i = 0; i < extra.pendingComments.length; ++i) {
1387
                attacher = extra.pendingComments[i];
1388
                if (node.range[0] >= attacher.comment.range[1]) {
1389
                    candidate = attacher.leading;
1390
                    if (candidate) {
1391
                        pos = candidate.range[0];
1392
                        len = candidate.range[1] - pos;
1393
                        if (node.range[0] <= pos && (node.range[1] - node.range[0] >= len)) {
1394
                            attacher.leading = node;
1395
                        }
1396
                    } else {
1397
                        attacher.leading = node;
1398
                    }
1399
                }
1400
                if (node.range[1] <= attacher.comment.range[0]) {
1401
                    candidate = attacher.trailing;
1402
                    if (candidate) {
1403
                        pos = candidate.range[0];
1404
                        len = candidate.range[1] - pos;
1405
                        if (node.range[0] <= pos && (node.range[1] - node.range[0] >= len)) {
1406
                            attacher.trailing = node;
1407
                        }
1408
                    } else {
1409
                        attacher.trailing = node;
1410
                    }
1411
                }
1412
            }
1413
        },
1414
1415
        markEnd: function (node) {
1416
            if (extra.range) {
1417
                node.range = [state.markerStack.pop(), index];
1418
            }
1419
            if (extra.loc) {
1420
                node.loc = {
1421
                    start: {
1422
                        line: state.markerStack.pop(),
1423
                        column: state.markerStack.pop()
1424
                    },
1425
                    end: {
1426
                        line: lineNumber,
1427
                        column: index - lineStart
1428
                    }
1429
                };
1430
                this.postProcess(node);
1431
            }
1432
            if (extra.attachComment) {
1433
                this.processComment(node);
1434
            }
1435
            return node;
1436
        },
1437
1438
        markEndIf: function (node) {
1439
            // mamacdon: in tolerant mode, node passed to the delegate may be null
1440
            if (!node || node.range || node.loc) {
1441
                if (extra.loc) {
1442
                    state.markerStack.pop();
1443
                    state.markerStack.pop();
1444
                }
1445
                if (extra.range) {
1446
                    state.markerStack.pop();
1447
                }
1448
            } else {
1449
                this.markEnd(node);
1450
            }
1451
            return node;
1452
        },
1453
1454
        postProcess: function (node) {
1455
            if (extra.source) {
1456
                node.loc.source = extra.source;
1457
            }
1458
            return node;
1459
        },
1460
1461
        createArrayExpression: function (elements) {
1462
            return {
1463
                type: Syntax.ArrayExpression,
1464
                elements: elements
1465
            };
1466
        },
1467
1468
        createAssignmentExpression: function (operator, left, right) {
1469
            return {
1470
                type: Syntax.AssignmentExpression,
1471
                operator: operator,
1472
                left: left,
1473
                right: right
1474
            };
1475
        },
1476
1477
        createBinaryExpression: function (operator, left, right) {
1478
            var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression :
1479
                        Syntax.BinaryExpression;
1480
            return {
1481
                type: type,
1482
                operator: operator,
1483
                left: left,
1484
                right: right
1485
            };
1486
        },
1487
1488
        createBlockStatement: function (body) {
1489
            return {
1490
                type: Syntax.BlockStatement,
1491
                body: body
1492
            };
1493
        },
1494
1495
        createBreakStatement: function (label) {
1496
            return {
1497
                type: Syntax.BreakStatement,
1498
                label: label
1499
            };
1500
        },
1501
1502
        createCallExpression: function (callee, args) {
1503
            return {
1504
                type: Syntax.CallExpression,
1505
                callee: callee,
1506
                'arguments': args
1507
            };
1508
        },
1509
1510
        createCatchClause: function (param, body) {
1511
            return {
1512
                type: Syntax.CatchClause,
1513
                param: param,
1514
                body: body
1515
            };
1516
        },
1517
1518
        createConditionalExpression: function (test, consequent, alternate) {
1519
            return {
1520
                type: Syntax.ConditionalExpression,
1521
                test: test,
1522
                consequent: consequent,
1523
                alternate: alternate
1524
            };
1525
        },
1526
1527
        createContinueStatement: function (label) {
1528
            return {
1529
                type: Syntax.ContinueStatement,
1530
                label: label
1531
            };
1532
        },
1533
1534
        createDebuggerStatement: function () {
1535
            return {
1536
                type: Syntax.DebuggerStatement
1537
            };
1538
        },
1539
1540
        createDoWhileStatement: function (body, test) {
1541
            return {
1542
                type: Syntax.DoWhileStatement,
1543
                body: body,
1544
                test: test
1545
            };
1546
        },
1547
1548
        createEmptyStatement: function () {
1549
            return {
1550
                type: Syntax.EmptyStatement
1551
            };
1552
        },
1553
1554
        createExpressionStatement: function (expression) {
1555
            return {
1556
                type: Syntax.ExpressionStatement,
1557
                expression: expression
1558
            };
1559
        },
1560
1561
        createForStatement: function (init, test, update, body) {
1562
            return {
1563
                type: Syntax.ForStatement,
1564
                init: init,
1565
                test: test,
1566
                update: update,
1567
                body: body
1568
            };
1569
        },
1570
1571
        createForInStatement: function (left, right, body) {
1572
            return {
1573
                type: Syntax.ForInStatement,
1574
                left: left,
1575
                right: right,
1576
                body: body,
1577
                each: false
1578
            };
1579
        },
1580
1581
        createFunctionDeclaration: function (id, params, defaults, body) {
1582
            return {
1583
                type: Syntax.FunctionDeclaration,
1584
                id: id,
1585
                params: params,
1586
                defaults: defaults,
1587
                body: body,
1588
                rest: null,
1589
                generator: false,
1590
                expression: false
1591
            };
1592
        },
1593
1594
        createFunctionExpression: function (id, params, defaults, body) {
1595
            return {
1596
                type: Syntax.FunctionExpression,
1597
                id: id,
1598
                params: params,
1599
                defaults: defaults,
1600
                body: body,
1601
                rest: null,
1602
                generator: false,
1603
                expression: false
1604
            };
1605
        },
1606
1607
        createIdentifier: function (name) {
1608
            return {
1609
                type: Syntax.Identifier,
1610
                name: name
1611
            };
1612
        },
1613
1614
        createIfStatement: function (test, consequent, alternate) {
1615
            return {
1616
                type: Syntax.IfStatement,
1617
                test: test,
1618
                consequent: consequent,
1619
                alternate: alternate
1620
            };
1621
        },
1622
1623
        createLabeledStatement: function (label, body) {
1624
            return {
1625
                type: Syntax.LabeledStatement,
1626
                label: label,
1627
                body: body
1628
            };
1629
        },
1630
1631
        createLiteral: function (token) {
1632
            return {
1633
                type: Syntax.Literal,
1634
                value: token.value,
1635
                raw: source.slice(token.range[0], token.range[1])
1636
            };
1637
        },
1638
1639
        createMemberExpression: function (accessor, object, property) {
1640
            return {
1641
                type: Syntax.MemberExpression,
1642
                computed: accessor === '[',
1643
                object: object,
1644
                property: property
1645
            };
1646
        },
1647
1648
        createNewExpression: function (callee, args) {
1649
            return {
1650
                type: Syntax.NewExpression,
1651
                callee: callee,
1652
                'arguments': args
1653
            };
1654
        },
1655
1656
        createObjectExpression: function (properties) {
1657
            return {
1658
                type: Syntax.ObjectExpression,
1659
                properties: properties
1660
            };
1661
        },
1662
1663
        createPostfixExpression: function (operator, argument) {
1664
            return {
1665
                type: Syntax.UpdateExpression,
1666
                operator: operator,
1667
                argument: argument,
1668
                prefix: false
1669
            };
1670
        },
1671
1672
        createProgram: function (body) {
1673
            return {
1674
                type: Syntax.Program,
1675
                body: body
1676
            };
1677
        },
1678
1679
        createProperty: function (kind, key, value) {
1680
            return {
1681
                type: Syntax.Property,
1682
                key: key,
1683
                value: value,
1684
                kind: kind
1685
            };
1686
        },
1687
1688
        createReturnStatement: function (argument) {
1689
            return {
1690
                type: Syntax.ReturnStatement,
1691
                argument: argument
1692
            };
1693
        },
1694
1695
        createSequenceExpression: function (expressions) {
1696
            return {
1697
                type: Syntax.SequenceExpression,
1698
                expressions: expressions
1699
            };
1700
        },
1701
1702
        createSwitchCase: function (test, consequent) {
1703
            return {
1704
                type: Syntax.SwitchCase,
1705
                test: test,
1706
                consequent: consequent
1707
            };
1708
        },
1709
1710
        createSwitchStatement: function (discriminant, cases) {
1711
            return {
1712
                type: Syntax.SwitchStatement,
1713
                discriminant: discriminant,
1714
                cases: cases
1715
            };
1716
        },
1717
1718
        createThisExpression: function () {
1719
            return {
1720
                type: Syntax.ThisExpression
1721
            };
1722
        },
1723
1724
        createThrowStatement: function (argument) {
1725
            return {
1726
                type: Syntax.ThrowStatement,
1727
                argument: argument
1728
            };
1729
        },
1730
1731
        createTryStatement: function (block, guardedHandlers, handlers, finalizer) {
1732
            return {
1733
                type: Syntax.TryStatement,
1734
                block: block,
1735
                guardedHandlers: guardedHandlers,
1736
                handlers: handlers,
1737
                finalizer: finalizer
1738
            };
1739
        },
1740
1741
        createUnaryExpression: function (operator, argument) {
1742
            if (operator === '++' || operator === '--') {
1743
                return {
1744
                    type: Syntax.UpdateExpression,
1745
                    operator: operator,
1746
                    argument: argument,
1747
                    prefix: true
1748
                };
1749
            }
1750
            return {
1751
                type: Syntax.UnaryExpression,
1752
                operator: operator,
1753
                argument: argument,
1754
                prefix: true
1755
            };
1756
        },
1757
1758
        createVariableDeclaration: function (declarations, kind) {
1759
            return {
1760
                type: Syntax.VariableDeclaration,
1761
                declarations: declarations,
1762
                kind: kind
1763
            };
1764
        },
1765
1766
        createVariableDeclarator: function (id, init) {
1767
            return {
1768
                type: Syntax.VariableDeclarator,
1769
                id: id,
1770
                init: init
1771
            };
1772
        },
1773
1774
        createWhileStatement: function (test, body) {
1775
            return {
1776
                type: Syntax.WhileStatement,
1777
                test: test,
1778
                body: body
1779
            };
1780
        },
1781
1782
        createWithStatement: function (object, body) {
1783
            return {
1784
                type: Syntax.WithStatement,
1785
                object: object,
1786
                body: body
1787
            };
1788
        }
1789
    };
1165
1790
1166
    // Return true if there is a line terminator before the next token.
1791
    // Return true if there is a line terminator before the next token.
1167
1792
Lines 1188-1200 Link Here
1188
            msg = messageFormat.replace(
1813
            msg = messageFormat.replace(
1189
                /%(\d)/g,
1814
                /%(\d)/g,
1190
                function (whole, index) {
1815
                function (whole, index) {
1191
                    return args[index] || '';
1816
                    assert(index < args.length, 'Message reference must be in range');
1817
                    return args[index];
1192
                }
1818
                }
1193
            );
1819
            );
1194
1820
1195
        if (typeof token.lineNumber === 'number') {
1821
        if (typeof token.lineNumber === 'number') {
1196
            error = new Error('Line ' + token.lineNumber + ': ' + msg);
1822
            error = new Error('Line ' + token.lineNumber + ': ' + msg);
1197
            error.index = token.range[0];
1823
            error.index = token.range[0];
1824
            // mamacdon a09739e
1825
            // mamacdon @ 1.0.0 esprima.js:1198
1198
            error.end = token.range[1];
1826
            error.end = token.range[1];
1199
            error.token = token.value;
1827
            error.token = token.value;
1200
            error.lineNumber = token.lineNumber;
1828
            error.lineNumber = token.lineNumber;
Lines 1206-1216 Link Here
1206
            error.column = index - lineStart + 1;
1834
            error.column = index - lineStart + 1;
1207
        }
1835
        }
1208
1836
1837
        error.description = msg;
1209
        throw error;
1838
        throw error;
1210
    }
1839
    }
1211
1840
1841
    // mamacdon: in tolerant mode, records the error and returns undefined. If non tolerant, throws.
1212
    function throwErrorTolerant() {
1842
    function throwErrorTolerant() {
1213
        var error;
1214
        try {
1843
        try {
1215
            throwError.apply(null, arguments);
1844
            throwError.apply(null, arguments);
1216
        } catch (e) {
1845
        } catch (e) {
Lines 1222-1233 Link Here
1222
        }
1851
        }
1223
    }
1852
    }
1224
1853
1225
1226
    // Throw an exception because of the token.
1854
    // Throw an exception because of the token.
1227
1855
1228
    function throwUnexpected(token) {
1856
    function throwUnexpected(token) {
1229
        var s;
1230
1231
        if (token.type === Token.EOF) {
1857
        if (token.type === Token.EOF) {
1232
            throwError(token, Messages.UnexpectedEOS);
1858
            throwError(token, Messages.UnexpectedEOS);
1233
        }
1859
        }
Lines 1248-1254 Link Here
1248
            if (isFutureReservedWord(token.value)) {
1874
            if (isFutureReservedWord(token.value)) {
1249
                throwError(token, Messages.UnexpectedReserved);
1875
                throwError(token, Messages.UnexpectedReserved);
1250
            } else if (strict && isStrictModeReservedWord(token.value)) {
1876
            } else if (strict && isStrictModeReservedWord(token.value)) {
1251
                throwError(token, Messages.StrictReservedWord);
1877
                throwErrorTolerant(token, Messages.StrictReservedWord);
1252
            }
1878
            }
1253
            throwError(token, Messages.UnexpectedToken, token.value);
1879
            throwError(token, Messages.UnexpectedToken, token.value);
1254
        }
1880
        }
Lines 1280-1305 Link Here
1280
    // Return true if the next token matches the specified punctuator.
1906
    // Return true if the next token matches the specified punctuator.
1281
1907
1282
    function match(value) {
1908
    function match(value) {
1283
        var token = lookahead();
1909
        return lookahead.type === Token.Punctuator && lookahead.value === value;
1284
        return token.type === Token.Punctuator && token.value === value;
1285
    }
1910
    }
1286
1911
1287
    // Return true if the next token matches the specified keyword
1912
    // Return true if the next token matches the specified keyword
1288
1913
1289
    function matchKeyword(keyword) {
1914
    function matchKeyword(keyword) {
1290
        var token = lookahead();
1915
        return lookahead.type === Token.Keyword && lookahead.value === keyword;
1291
        return token.type === Token.Keyword && token.value === keyword;
1292
    }
1916
    }
1293
1917
1294
    // Return true if the next token is an assignment operator
1918
    // Return true if the next token is an assignment operator
1295
1919
1296
    function matchAssign() {
1920
    function matchAssign() {
1297
        var token = lookahead(),
1921
        var op;
1298
            op = token.value;
1299
1922
1300
        if (token.type !== Token.Punctuator) {
1923
        if (lookahead.type !== Token.Punctuator) {
1301
            return false;
1924
            return false;
1302
        }
1925
        }
1926
        op = lookahead.value;
1303
        return op === '=' ||
1927
        return op === '=' ||
1304
            op === '*=' ||
1928
            op === '*=' ||
1305
            op === '/=' ||
1929
            op === '/=' ||
Lines 1315-1324 Link Here
1315
    }
1939
    }
1316
1940
1317
    function consumeSemicolon() {
1941
    function consumeSemicolon() {
1318
        var token, line;
1942
        var line;
1319
1943
1320
        // Catch the very common case first.
1944
        // Catch the very common case first: immediately a semicolon (char #59).
1321
        if (source[index] === ';') {
1945
        if (source.charCodeAt(index) === 59) {
1322
            lex();
1946
            lex();
1323
            return;
1947
            return;
1324
        }
1948
        }
Lines 1334-1377 Link Here
1334
            return;
1958
            return;
1335
        }
1959
        }
1336
1960
1337
        token = lookahead();
1961
        if (lookahead.type !== Token.EOF && !match('}')) {
1338
        if (token.type !== Token.EOF && !match('}')) {        
1962
        	var badToken = lookahead;
1339
            if (extra.errors) {
1963
        	if (extra.errors) {
1340
                rewind();
1964
                rewind(); // mutates lookahead
1341
            }
1965
            }
1342
            throwUnexpected(token);
1966
            throwUnexpected(badToken);
1343
        }
1967
        }
1344
        return;
1345
    }
1968
    }
1346
1969
1347
    // Return true if provided expression is LeftHandSideExpression
1970
    // Return true if provided expression is LeftHandSideExpression
1348
1971
1349
    function isLeftHandSide(expr) {
1972
    function isLeftHandSide(expr) {
1350
        switch (expr.type) {
1973
        return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
1351
        case 'AssignmentExpression':
1352
        case 'BinaryExpression':
1353
        case 'ConditionalExpression':
1354
        case 'LogicalExpression':
1355
        case 'SequenceExpression':
1356
        case 'UnaryExpression':
1357
        case 'UpdateExpression':
1358
            return false;
1359
        }
1360
        return true;
1361
    }
1974
    }
1362
1975
1363
    // 11.1.4 Array Initialiser
1976
    // 11.1.4 Array Initialiser
1364
1977
1365
    function parseArrayInitialiser() {
1978
    function parseArrayInitialiser() {
1366
        var elements = [],
1979
        var elements = [];
1367
            undef;
1368
1980
1369
        expect('[');
1981
        expect('[');
1370
1982
1371
        while (!match(']')) {
1983
        while (!match(']')) {
1372
            if (match(',')) {
1984
            if (match(',')) {
1373
                lex();
1985
                lex();
1374
                elements.push(undef);
1986
                elements.push(null);
1375
            } else {
1987
            } else {
1376
                elements.push(parseAssignmentExpression());
1988
                elements.push(parseAssignmentExpression());
1377
1989
Lines 1383-1392 Link Here
1383
1995
1384
        expect(']');
1996
        expect(']');
1385
1997
1386
        return {
1998
        return delegate.createArrayExpression(elements);
1387
            type: Syntax.ArrayExpression,
1388
            elements: elements
1389
        };
1390
    }
1999
    }
1391
2000
1392
    // 11.1.5 Object Initialiser
2001
    // 11.1.5 Object Initialiser
Lines 1395-1437 Link Here
1395
        var previousStrict, body;
2004
        var previousStrict, body;
1396
2005
1397
        previousStrict = strict;
2006
        previousStrict = strict;
2007
        skipComment();
2008
        delegate.markStart();
1398
        body = parseFunctionSourceElements();
2009
        body = parseFunctionSourceElements();
1399
        if (first && strict && isRestrictedWord(param[0].name)) {
2010
        if (first && strict && isRestrictedWord(param[0].name)) {
1400
            throwError(first, Messages.StrictParamName);
2011
            throwErrorTolerant(first, Messages.StrictParamName);
1401
        }
2012
        }
1402
        strict = previousStrict;
2013
        strict = previousStrict;
1403
2014
        return delegate.markEnd(delegate.createFunctionExpression(null, param, [], body));
1404
        return {
1405
            type: Syntax.FunctionExpression,
1406
            id: null,
1407
            params: param,
1408
            body: body
1409
        };
1410
    }
2015
    }
1411
2016
1412
    function parseObjectPropertyKey() {
2017
    function parseObjectPropertyKey() {
1413
        var token = lex();
2018
        var token;
2019
2020
        skipComment();
2021
        delegate.markStart();
2022
        token = lex();
1414
2023
1415
        // Note: This function is called only from parseObjectProperty(), where
2024
        // Note: This function is called only from parseObjectProperty(), where
1416
        // EOF and Punctuator tokens are already filtered out.
2025
        // EOF and Punctuator tokens are already filtered out.
1417
2026
1418
        if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
2027
        if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
1419
            if (strict && token.octal) {
2028
            if (strict && token.octal) {
1420
                throwError(token, Messages.StrictOctalLiteral);
2029
                throwErrorTolerant(token, Messages.StrictOctalLiteral);
1421
            }
2030
            }
1422
            return createLiteral(token);
2031
            return delegate.markEnd(delegate.createLiteral(token));
1423
        }
2032
        }
1424
2033
1425
        return {
2034
        return delegate.markEnd(delegate.createIdentifier(token.value));
1426
            type: Syntax.Identifier,
1427
            name: token.value
1428
        };
1429
    }
2035
    }
1430
2036
1431
    function parseObjectProperty() {
2037
    function parseObjectProperty() {
1432
        var token, key, id, param;
2038
        var token, key, id, value, param;
1433
2039
1434
        token = lookahead();
2040
        token = lookahead;
2041
        skipComment();
2042
        delegate.markStart();
1435
2043
1436
        if (token.type === Token.Identifier) {
2044
        if (token.type === Token.Identifier) {
1437
2045
Lines 1443-1624 Link Here
1443
                key = parseObjectPropertyKey();
2051
                key = parseObjectPropertyKey();
1444
                expect('(');
2052
                expect('(');
1445
                expect(')');
2053
                expect(')');
1446
                return {
2054
                value = parsePropertyFunction([]);
1447
                    type: Syntax.Property,
2055
                return delegate.markEnd(delegate.createProperty('get', key, value));
1448
                    key: key,
2056
            }
1449
                    value: parsePropertyFunction([]),
2057
            if (token.value === 'set' && !match(':')) {
1450
                    kind: 'get'
1451
                };
1452
            } else if (token.value === 'set' && !match(':')) {
1453
                key = parseObjectPropertyKey();
2058
                key = parseObjectPropertyKey();
1454
                expect('(');
2059
                expect('(');
1455
                token = lookahead();
2060
                token = lookahead;
1456
                if (token.type !== Token.Identifier) {
2061
                if (token.type !== Token.Identifier) {
1457
                    throwUnexpected(lex());
2062
                    expect(')');
2063
                    throwErrorTolerant(token, Messages.UnexpectedToken, token.value);
2064
                    value = parsePropertyFunction([]);
2065
                } else {
2066
                    param = [ parseVariableIdentifier() ];
2067
                    expect(')');
2068
                    value = parsePropertyFunction(param, token);
1458
                }
2069
                }
1459
                param = [ parseVariableIdentifier() ];
2070
                return delegate.markEnd(delegate.createProperty('set', key, value));
1460
                expect(')');
1461
                return {
1462
                    type: Syntax.Property,
1463
                    key: key,
1464
                    value: parsePropertyFunction(param, token),
1465
                    kind: 'set'
1466
                };
1467
            } else {
1468
                expect(':');
1469
                return {
1470
                    type: Syntax.Property,
1471
                    key: id,
1472
                    value: parseAssignmentExpression(),
1473
                    kind: 'init'
1474
                };
1475
            }
2071
            }
1476
        } else if (token.type === Token.EOF || token.type === Token.Punctuator) {
2072
            //mrennie https://bugs.eclipse.org/bugs/show_bug.cgi?id=432956
2073
            var prev = token;
2074
            token = advance();
2075
            if(token.value === ':') {
2076
            	token = lex(); // eat the ':' so the assignment parsing starts on the correct index
2077
            	try {
2078
	            	value = parseAssignmentExpression();
2079
	            	return delegate.markEnd(delegate.createProperty('init', id, value));
2080
            	} catch(e) {
2081
            		//process the exception
2082
            		return null;
2083
            	}
2084
            } else if(token.type === Token.Punctuator && token.value === '}') {
2085
            	throwErrorTolerant(prev, Messages.UnexpectedToken, prev.value);
2086
            	return null;
2087
            } else {
2088
            	throwErrorTolerant(prev, Messages.UnexpectedToken, prev.value);
2089
            	if(token.type === Token.Identifier) {
2090
            		//if the next token is an identifer, start over
2091
            		return null;
2092
            	}
2093
            	while(token.type !== Token.EOF) {
2094
            		if(token.type === Token.Punctuator && (token.value === ',' || token.value === '}')) {
2095
		            	//entering a prop, not complete, return null
2096
		            	return null;
2097
		            } else {
2098
            			token = lex(); // the token if we skipped it
2099
            		}
2100
            		token = advance();
2101
            	}
2102
            }
2103
            return null;
2104
        }
2105
        if (token.type === Token.EOF || token.type === Token.Punctuator) {
1477
            throwUnexpected(token);
2106
            throwUnexpected(token);
1478
        } else {
2107
        } else {
1479
            key = parseObjectPropertyKey();
2108
            key = parseObjectPropertyKey();
1480
            expect(':');
2109
            expect(':');
1481
            return {
2110
            value = parseAssignmentExpression();
1482
                type: Syntax.Property,
2111
            return delegate.markEnd(delegate.createProperty('init', key, value));
1483
                key: key,
1484
                value: parseAssignmentExpression(),
1485
                kind: 'init'
1486
            };
1487
        }
2112
        }
1488
    }
2113
    }
1489
2114
1490
    function parseObjectInitialiser() {
2115
    function parseObjectInitialiser() {
1491
        var token, properties = [], property, name, kind, map = {}, toString = String;
2116
        var properties = [], property, name, key, kind, map = {}, toString = String;
1492
2117
1493
        expect('{');
2118
        expect('{');
1494
2119
1495
        while (!match('}')) {
2120
        while (!match('}')) {
1496
            property = parseObjectProperty();
2121
            property = parseObjectProperty();
1497
2122
            //mrennie https://bugs.eclipse.org/bugs/show_bug.cgi?id=432956
2123
			if(!property) {
2124
				continue;
2125
			}
1498
            if (property.key.type === Syntax.Identifier) {
2126
            if (property.key.type === Syntax.Identifier) {
1499
                name = property.key.name;
2127
                name = property.key.name;
1500
            } else {
2128
            } else {
1501
                name = toString(property.key.value);
2129
                name = toString(property.key.value);
1502
            }
2130
            }
1503
            kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
2131
            kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
1504
            if (Object.prototype.hasOwnProperty.call(map, name)) {
2132
1505
                if (map[name] === PropertyKind.Data) {
2133
            key = '$' + name;
2134
            if (Object.prototype.hasOwnProperty.call(map, key)) {
2135
                if (map[key] === PropertyKind.Data) {
1506
                    if (strict && kind === PropertyKind.Data) {
2136
                    if (strict && kind === PropertyKind.Data) {
1507
                        throwErrorTolerant({}, Messages.StrictDuplicateProperty);
2137
                        throwErrorTolerant({}, Messages.StrictDuplicateProperty);
1508
                    } else if (kind !== PropertyKind.Data) {
2138
                    } else if (kind !== PropertyKind.Data) {
1509
                        throwError({}, Messages.AccessorDataProperty);
2139
                        throwErrorTolerant({}, Messages.AccessorDataProperty);
1510
                    }
2140
                    }
1511
                } else {
2141
                } else {
1512
                    if (kind === PropertyKind.Data) {
2142
                    if (kind === PropertyKind.Data) {
1513
                        throwError({}, Messages.AccessorDataProperty);
2143
                        throwErrorTolerant({}, Messages.AccessorDataProperty);
1514
                    } else if (map[name] & kind) {
2144
                    } else if (map[key] & kind) {
1515
                        throwError({}, Messages.AccessorGetSet);
2145
                        throwErrorTolerant({}, Messages.AccessorGetSet);
1516
                    }
2146
                    }
1517
                }
2147
                }
1518
                map[name] |= kind;
2148
                map[key] |= kind;
1519
            } else {
2149
            } else {
1520
                map[name] = kind;
2150
                map[key] = kind;
1521
            }
2151
            }
1522
2152
1523
            properties.push(property);
2153
            properties.push(property);
1524
2154
1525
            if (!match('}')) {
2155
            if (!match('}')) {
1526
                expect(',');
2156
            	//mrennie https://bugs.eclipse.org/bugs/show_bug.cgi?id=432956
2157
            	var token = lookahead;
2158
            	if(token.type !== Token.Punctuator && token.value !== ',') {
2159
            		if(extra.tokens && extra.tokens.length > 0) {
2160
            			token = extra.tokens[extra.tokens.length-1];
2161
            		}
2162
            		throwErrorTolerant(token, Messages.MissingToken, ',');
2163
            	} else {
2164
            		lex();
2165
            	}
1527
            }
2166
            }
1528
        }
2167
        }
1529
2168
1530
        expect('}');
2169
        expect('}');
1531
2170
1532
        return {
2171
        return delegate.createObjectExpression(properties);
1533
            type: Syntax.ObjectExpression,
1534
            properties: properties
1535
        };
1536
    }
2172
    }
2173
2174
    // 11.1.6 The Grouping Operator
2175
2176
    function parseGroupExpression() {
2177
        var expr;
2178
2179
        expect('(');
2180
2181
        expr = parseExpression();
2182
2183
        expect(')');
2184
2185
        return expr;
2186
    }
2187
1537
2188
1538
    // 11.1 Primary Expressions
2189
    // 11.1 Primary Expressions
1539
2190
1540
    function parsePrimaryExpression() {
2191
    function parsePrimaryExpression() {
1541
        var expr,
2192
        var type, token, expr;
1542
            token = lookahead(),
1543
            type = token.type;
1544
1545
        if (type === Token.Identifier) {
1546
            return {
1547
                type: Syntax.Identifier,
1548
                name: lex().value
1549
            };
1550
        }
1551
1552
        if (type === Token.StringLiteral || type === Token.NumericLiteral) {
1553
            if (strict && token.octal) {
1554
                throwErrorTolerant(token, Messages.StrictOctalLiteral);
1555
            }
1556
            return createLiteral(lex());
1557
        }
1558
1559
        if (type === Token.Keyword) {
1560
            if (matchKeyword('this')) {
1561
                lex();
1562
                return {
1563
                    type: Syntax.ThisExpression
1564
                };
1565
            }
1566
1567
            if (matchKeyword('function')) {
1568
                return parseFunctionExpression();
1569
            }
1570
        }
1571
1572
        if (type === Token.BooleanLiteral) {
1573
            lex();
1574
            token.value = (token.value === 'true');
1575
            return createLiteral(token);
1576
        }
1577
1578
        if (type === Token.NullLiteral) {
1579
            lex();
1580
            token.value = null;
1581
            return createLiteral(token);
1582
        }
1583
1584
        if (match('[')) {
1585
            return parseArrayInitialiser();
1586
        }
1587
1588
        if (match('{')) {
1589
            return parseObjectInitialiser();
1590
        }
1591
2193
1592
        if (match('(')) {
2194
        if (match('(')) {
1593
            lex();
2195
            return parseGroupExpression();
1594
            state.lastParenthesized = expr = parseExpression();
1595
            expect(')');
1596
            return expr;
1597
        }
2196
        }
1598
2197
1599
        if (match('/') || match('/=')) {
2198
        type = lookahead.type;
1600
            return createLiteral(scanRegExp());
2199
        delegate.markStart();
2200
2201
        if (type === Token.Identifier) {
2202
            expr =  delegate.createIdentifier(lex().value);
2203
        } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
2204
            if (strict && lookahead.octal) {
2205
                throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
2206
            }
2207
            expr = delegate.createLiteral(lex());
2208
        } else if (type === Token.Keyword) {
2209
            if (matchKeyword('this')) {
2210
                lex();
2211
                expr = delegate.createThisExpression();
2212
            } else if (matchKeyword('function')) {
2213
                expr = parseFunctionExpression();
2214
            }
2215
        } else if (type === Token.BooleanLiteral) {
2216
            token = lex();
2217
            token.value = (token.value === 'true');
2218
            expr = delegate.createLiteral(token);
2219
        } else if (type === Token.NullLiteral) {
2220
            token = lex();
2221
            token.value = null;
2222
            expr = delegate.createLiteral(token);
2223
        } else if (match('[')) {
2224
            expr = parseArrayInitialiser();
2225
        } else if (match('{')) {
2226
            expr = parseObjectInitialiser();
2227
        } else if (match('/') || match('/=')) {
2228
            if (typeof extra.tokens !== 'undefined') {
2229
                expr = delegate.createLiteral(collectRegex());
2230
            } else {
2231
                expr = delegate.createLiteral(scanRegExp());
2232
            }
2233
            peek();
2234
        }
2235
2236
        if (expr) {
2237
            return delegate.markEnd(expr);
1601
        }
2238
        }
1602
2239
1603
        return throwUnexpected(lex());
2240
        return throwUnexpected(lex());
1604
    }
2241
    }
1605
2242
1606
    /**
1607
     * add the error if not already reported.
1608
     */
1609
    function pushError(error) {
1610
        var len = extra.errors.length;
1611
        for (var e=0; e < len; e++) {
1612
            var existingError = extra.errors[e];
1613
            if (existingError.index === error.index && existingError.message === error.message) {
1614
                return; // do not add duplicate
1615
            }
1616
        }
1617
        extra.errors.push(error);
1618
    }
1619
1620
    // 11.2 Left-Hand-Side Expressions
2243
    // 11.2 Left-Hand-Side Expressions
1621
2244
2245
    // mamacdon 1420b19
1622
    function parseArguments() {
2246
    function parseArguments() {
1623
        var args = [];
2247
        var args = [];
1624
2248
Lines 1657-1669 Link Here
1657
2281
1658
        return args;
2282
        return args;
1659
    }
2283
    }
2284
2285
    function parseNonComputedProperty() {
2286
        var token;
2287
2288
		if (lookahead.lineNumber !== lineNumber) {
2289
			// Token giving our identifier name lies on the following line, so go there before marking start
2290
			index = lookahead.lineStart;
2291
		}
2292
        delegate.markStart();
2293
        token = lex();
2294
2295
        if (!isIdentifierName(token)) {
2296
        	if (extra.errors) {
2297
                attemptRecoveryNonComputedProperty(token);
2298
            }
2299
            throwUnexpected(token);
2300
            // return null; // unecessary
2301
        }
2302
2303
        return delegate.markEnd(delegate.createIdentifier(token.value));
2304
    }
2305
2306
    function parseNonComputedMember() {
2307
        expect('.');
2308
2309
        return parseNonComputedProperty();
2310
    }
2311
2312
    function parseComputedMember() {
2313
        var expr;
2314
2315
        expect('[');
2316
2317
        expr = parseExpression();
2318
2319
        expect(']');
2320
2321
        return expr;
2322
    }
2323
2324
    function parseNewExpression() {
2325
        var callee, args;
2326
2327
        delegate.markStart();
2328
        expectKeyword('new');
2329
        callee = parseLeftHandSideExpression();
2330
        args = match('(') ? parseArguments() : [];
2331
2332
        return delegate.markEnd(delegate.createNewExpression(callee, args));
2333
    }
2334
2335
    function parseLeftHandSideExpressionAllowCall() {
2336
        var marker, previousAllowIn, expr, args, property;
2337
2338
        marker = createLocationMarker();
2339
2340
        previousAllowIn = state.allowIn;
2341
        state.allowIn = true;
2342
        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
2343
        state.allowIn = previousAllowIn;
2344
2345
        while (match('.') || match('[') || match('(')) {
2346
            if (match('(')) {
2347
                args = parseArguments();
2348
                expr = delegate.createCallExpression(expr, args);
2349
            } else if (match('[')) {
2350
                property = parseComputedMember();
2351
                expr = delegate.createMemberExpression('[', expr, property);
2352
            } else {
2353
                property = parseNonComputedMember();
2354
                expr = delegate.createMemberExpression('.', expr, property);
2355
            }
2356
            if (marker) {
2357
                marker.end();
2358
                marker.apply(expr);
2359
            }
2360
        }
2361
2362
        return expr;
2363
    }
2364
2365
    function parseLeftHandSideExpression() {
2366
        var marker, previousAllowIn, expr, property;
2367
2368
        marker = createLocationMarker();
2369
2370
        previousAllowIn = state.allowIn;
2371
        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
2372
        state.allowIn = previousAllowIn;
2373
2374
        while (match('.') || match('[')) {
2375
            if (match('[')) {
2376
                property = parseComputedMember();
2377
                expr = delegate.createMemberExpression('[', expr, property);
2378
            } else {
2379
                property = parseNonComputedMember();
2380
                expr = delegate.createMemberExpression('.', expr, property);
2381
            }
2382
            if (marker) {
2383
                marker.end();
2384
                marker.apply(expr);
2385
            }
2386
        }
2387
2388
        return expr;
2389
    }
2390
2391
    // 11.3 Postfix Expressions
2392
2393
    function parsePostfixExpression() {
2394
        var expr, token;
2395
2396
        delegate.markStart();
2397
        expr = parseLeftHandSideExpressionAllowCall();
2398
2399
        if (lookahead.type === Token.Punctuator) {
2400
            if ((match('++') || match('--')) && !peekLineTerminator()) {
2401
                // 11.3.1, 11.3.2
2402
                if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
2403
                    throwErrorTolerant({}, Messages.StrictLHSPostfix);
2404
                }
2405
2406
                if (!isLeftHandSide(expr)) {
2407
                    throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2408
                }
2409
2410
                token = lex();
2411
                expr = delegate.createPostfixExpression(token.value, expr);
2412
            }
2413
        }
2414
2415
        return delegate.markEndIf(expr);
2416
    }
2417
2418
    // 11.4 Unary Operators
2419
2420
    function parseUnaryExpression() {
2421
        var token, expr;
2422
2423
        delegate.markStart();
2424
2425
        if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
2426
            expr = parsePostfixExpression();
2427
        } else if (match('++') || match('--')) {
2428
            token = lex();
2429
            expr = parseUnaryExpression();
2430
            // 11.4.4, 11.4.5
2431
            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
2432
                throwErrorTolerant({}, Messages.StrictLHSPrefix);
2433
            }
2434
2435
            if (!isLeftHandSide(expr)) {
2436
                throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2437
            }
2438
2439
            expr = delegate.createUnaryExpression(token.value, expr);
2440
        } else if (match('+') || match('-') || match('~') || match('!')) {
2441
            token = lex();
2442
            expr = parseUnaryExpression();
2443
            expr = delegate.createUnaryExpression(token.value, expr);
2444
        } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
2445
            token = lex();
2446
            expr = parseUnaryExpression();
2447
            expr = delegate.createUnaryExpression(token.value, expr);
2448
            if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
2449
                throwErrorTolerant({}, Messages.StrictDelete);
2450
            }
2451
        } else {
2452
            expr = parsePostfixExpression();
2453
        }
2454
2455
        return delegate.markEndIf(expr);
2456
    }
2457
2458
    function binaryPrecedence(token, allowIn) {
2459
        var prec = 0;
2460
2461
        if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
2462
            return 0;
2463
        }
2464
2465
        switch (token.value) {
2466
        case '||':
2467
            prec = 1;
2468
            break;
2469
2470
        case '&&':
2471
            prec = 2;
2472
            break;
2473
2474
        case '|':
2475
            prec = 3;
2476
            break;
2477
2478
        case '^':
2479
            prec = 4;
2480
            break;
2481
2482
        case '&':
2483
            prec = 5;
2484
            break;
2485
2486
        case '==':
2487
        case '!=':
2488
        case '===':
2489
        case '!==':
2490
            prec = 6;
2491
            break;
2492
2493
        case '<':
2494
        case '>':
2495
        case '<=':
2496
        case '>=':
2497
        case 'instanceof':
2498
            prec = 7;
2499
            break;
2500
2501
        case 'in':
2502
            prec = allowIn ? 7 : 0;
2503
            break;
2504
2505
        case '<<':
2506
        case '>>':
2507
        case '>>>':
2508
            prec = 8;
2509
            break;
2510
2511
        case '+':
2512
        case '-':
2513
            prec = 9;
2514
            break;
2515
2516
        case '*':
2517
        case '/':
2518
        case '%':
2519
            prec = 11;
2520
            break;
2521
2522
        default:
2523
            break;
2524
        }
2525
2526
        return prec;
2527
    }
2528
2529
    // 11.5 Multiplicative Operators
2530
    // 11.6 Additive Operators
2531
    // 11.7 Bitwise Shift Operators
2532
    // 11.8 Relational Operators
2533
    // 11.9 Equality Operators
2534
    // 11.10 Binary Bitwise Operators
2535
    // 11.11 Binary Logical Operators
2536
2537
    function parseBinaryExpression() {
2538
        var marker, markers, expr, token, prec, stack, right, operator, left, i;
2539
2540
        marker = createLocationMarker();
2541
        left = parseUnaryExpression();
2542
2543
        token = lookahead;
2544
        prec = binaryPrecedence(token, state.allowIn);
2545
        if (prec === 0) {
2546
            return left;
2547
        }
2548
        token.prec = prec;
2549
        lex();
2550
2551
        markers = [marker, createLocationMarker()];
2552
        right = parseUnaryExpression();
2553
2554
        stack = [left, token, right];
2555
2556
        while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) {
2557
2558
            // Reduce: make a binary expression from the three topmost entries.
2559
            while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
2560
                right = stack.pop();
2561
                operator = stack.pop().value;
2562
                left = stack.pop();
2563
                expr = delegate.createBinaryExpression(operator, left, right);
2564
                markers.pop();
2565
                marker = markers.pop();
2566
                if (marker) {
2567
                    marker.end();
2568
                    marker.apply(expr);
2569
                }
2570
                stack.push(expr);
2571
                markers.push(marker);
2572
            }
2573
2574
            // Shift.
2575
            token = lex();
2576
            token.prec = prec;
2577
            stack.push(token);
2578
            markers.push(createLocationMarker());
2579
            expr = parseUnaryExpression();
2580
            stack.push(expr);
2581
        }
2582
2583
        // Final reduce to clean-up the stack.
2584
        i = stack.length - 1;
2585
        expr = stack[i];
2586
        markers.pop();
2587
        while (i > 1) {
2588
            expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
2589
            i -= 2;
2590
            marker = markers.pop();
2591
            if (marker) {
2592
                marker.end();
2593
                marker.apply(expr);
2594
            }
2595
        }
2596
2597
        return expr;
2598
    }
2599
2600
2601
    // 11.12 Conditional Operator
2602
2603
    function parseConditionalExpression() {
2604
        var expr, previousAllowIn, consequent, alternate;
2605
2606
        delegate.markStart();
2607
        expr = parseBinaryExpression();
2608
2609
        if (match('?')) {
2610
            lex();
2611
            previousAllowIn = state.allowIn;
2612
            state.allowIn = true;
2613
            consequent = parseAssignmentExpression();
2614
            state.allowIn = previousAllowIn;
2615
            expect(':');
2616
            alternate = parseAssignmentExpression();
2617
2618
            expr = delegate.markEnd(delegate.createConditionalExpression(expr, consequent, alternate));
2619
        } else {
2620
            delegate.markEnd({});
2621
        }
2622
2623
        return expr;
2624
    }
2625
2626
    // 11.13 Assignment Operators
2627
2628
    function parseAssignmentExpression() {
2629
        var token, left, right, node;
2630
2631
        token = lookahead;
2632
        delegate.markStart();
2633
        node = left = parseConditionalExpression();
2634
2635
        if (matchAssign()) {
2636
            // LeftHandSideExpression
2637
            if (!isLeftHandSide(left)) {
2638
                throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2639
            }
2640
2641
            // 11.13.1
2642
            if (strict && left.type === Syntax.Identifier && isRestrictedWord(left.name)) {
2643
                throwErrorTolerant(token, Messages.StrictLHSAssignment);
2644
            }
2645
2646
            token = lex();
2647
            right = parseAssignmentExpression();
2648
            node = delegate.createAssignmentExpression(token.value, left, right);
2649
        }
2650
2651
        return delegate.markEndIf(node);
2652
    }
2653
2654
    // 11.14 Comma Operator
2655
2656
    function parseExpression() {
2657
        var expr;
2658
2659
        delegate.markStart();
2660
        expr = parseAssignmentExpression();
2661
2662
        if (match(',')) {
2663
            expr = delegate.createSequenceExpression([ expr ]);
2664
2665
            while (index < length) {
2666
                if (!match(',')) {
2667
                    break;
2668
                }
2669
                lex();
2670
                expr.expressions.push(parseAssignmentExpression());
2671
            }
2672
        }
2673
2674
        return delegate.markEndIf(expr);
2675
    }
2676
2677
    // 12.1 Block
2678
2679
    function parseStatementList() {
2680
        var list = [],
2681
            statement;
2682
2683
        while (index < length) {
2684
            if (match('}')) {
2685
                break;
2686
            }
2687
            statement = parseSourceElement();
2688
            if (typeof statement === 'undefined') {
2689
                break;
2690
            }
2691
            list.push(statement);
2692
        }
2693
2694
        return list;
2695
    }
2696
2697
    function parseBlock() {
2698
        var block;
2699
2700
        skipComment();
2701
        delegate.markStart();
2702
        expect('{');
2703
2704
        block = parseStatementList();
2705
2706
        // mamacdon 853a9865
2707
        // @ 1.0.0 esprima.js:2204
2708
        //expect('}');
2709
        expectConditionCloseBracketWrapThrow();
2710
2711
        return delegate.markEnd(delegate.createBlockStatement(block));
2712
    }
2713
2714
    // 12.2 Variable Statement
2715
2716
    function parseVariableIdentifier() {
2717
        var token;
2718
2719
        skipComment();
2720
        delegate.markStart();
2721
        token = lex();
2722
2723
        if (token.type !== Token.Identifier) {
2724
            throwUnexpected(token);
2725
        }
2726
2727
        return delegate.markEnd(delegate.createIdentifier(token.value));
2728
    }
2729
2730
    function parseVariableDeclaration(kind) {
2731
        var init = null, id;
2732
2733
        skipComment();
2734
        delegate.markStart();
2735
        id = parseVariableIdentifier();
2736
2737
        // 12.2.1
2738
        if (strict && isRestrictedWord(id.name)) {
2739
            throwErrorTolerant({}, Messages.StrictVarName);
2740
        }
2741
2742
        if (kind === 'const') {
2743
            expect('=');
2744
            init = parseAssignmentExpression();
2745
        } else if (match('=')) {
2746
            lex();
2747
            init = parseAssignmentExpression();
2748
        }
2749
2750
        return delegate.markEnd(delegate.createVariableDeclarator(id, init));
2751
    }
2752
2753
    function parseVariableDeclarationList(kind) {
2754
        var list = [];
2755
2756
        do {
2757
            list.push(parseVariableDeclaration(kind));
2758
            if (!match(',')) {
2759
                break;
2760
            }
2761
            lex();
2762
        } while (index < length);
2763
2764
        return list;
2765
    }
2766
2767
    function parseVariableStatement() {
2768
        var declarations;
2769
2770
        expectKeyword('var');
2771
2772
        declarations = parseVariableDeclarationList();
2773
2774
        consumeSemicolon();
2775
2776
        return delegate.createVariableDeclaration(declarations, 'var');
2777
    }
2778
2779
    // kind may be `const` or `let`
2780
    // Both are experimental and not in the specification yet.
2781
    // see http://wiki.ecmascript.org/doku.php?id=harmony:const
2782
    // and http://wiki.ecmascript.org/doku.php?id=harmony:let
2783
    function parseConstLetDeclaration(kind) {
2784
        var declarations;
2785
2786
        skipComment();
2787
        delegate.markStart();
2788
2789
        expectKeyword(kind);
2790
2791
        declarations = parseVariableDeclarationList(kind);
2792
2793
        consumeSemicolon();
2794
2795
        return delegate.markEnd(delegate.createVariableDeclaration(declarations, kind));
2796
    }
2797
2798
    // 12.3 Empty Statement
2799
2800
    function parseEmptyStatement() {
2801
        expect(';');
2802
        return delegate.createEmptyStatement();
2803
    }
2804
2805
    // 12.4 Expression Statement
2806
2807
    function parseExpressionStatement() {
2808
        var expr = parseExpression();
2809
        consumeSemicolon();
2810
        return delegate.createExpressionStatement(expr);
2811
    }
2812
2813
    // 12.5 If statement
2814
2815
    function parseIfStatement() {
2816
    	
2817
        var test, consequent, alternate;
2818
2819
        expectKeyword('if');
2820
2821
        expect('(');
2822
2823
        test = parseExpression();
2824
2825
        // mamacdon 853a9865
2826
        //expect(')');
2827
        expectConditionCloseParenWrapThrow();
2828
2829
        consequent = parseStatement();
2830
        // mamacdon 853a9865: required because of the check in wrapTracking that returns nothing if node is undefined
2831
		// TODO: delegate handles tracking now, check if this test is still needed
2832
        if (!consequent) {
2833
            consequent = null;
2834
        }
2835
        if (matchKeyword('else')) {
2836
            lex();
2837
            alternate = parseStatement();
2838
        } else {
2839
            alternate = null;
2840
        }
2841
2842
        return delegate.createIfStatement(test, consequent, alternate);
2843
    }
2844
2845
    // 12.6 Iteration Statements
2846
2847
    function parseDoWhileStatement() {
2848
        var body, test, oldInIteration;
2849
2850
        expectKeyword('do');
2851
2852
        oldInIteration = state.inIteration;
2853
        state.inIteration = true;
2854
2855
        body = parseStatement();
2856
2857
        state.inIteration = oldInIteration;
2858
2859
        expectKeyword('while');
2860
2861
        expect('(');
2862
2863
        test = parseExpression();
2864
2865
        expect(')');
2866
2867
        if (match(';')) {
2868
            lex();
2869
        }
2870
2871
        return delegate.createDoWhileStatement(body, test);
2872
    }
2873
2874
    function parseWhileStatement() {
2875
        var test, body, oldInIteration;
2876
2877
        expectKeyword('while');
2878
2879
        expect('(');
2880
2881
        test = parseExpression();
2882
2883
        // mamacdon 853a9865
2884
        //expect(')');
2885
        expectConditionCloseParenWrapThrow();
2886
2887
        oldInIteration = state.inIteration;
2888
        state.inIteration = true;
2889
2890
        body = parseStatement();
2891
2892
        state.inIteration = oldInIteration;
2893
2894
        return delegate.createWhileStatement(test, body);
2895
    }
2896
2897
    function parseForVariableDeclaration() {
2898
        var token, declarations;
2899
2900
        delegate.markStart();
2901
        token = lex();
2902
        declarations = parseVariableDeclarationList();
2903
2904
        return delegate.markEnd(delegate.createVariableDeclaration(declarations, token.value));
2905
    }
2906
2907
    function parseForStatement() {
2908
        var init, test, update, left, right, body, oldInIteration;
2909
2910
        init = test = update = null;
2911
2912
        expectKeyword('for');
2913
2914
        expect('(');
2915
2916
        if (match(';')) {
2917
            lex();
2918
        } else {
2919
            if (matchKeyword('var') || matchKeyword('let')) {
2920
                state.allowIn = false;
2921
                init = parseForVariableDeclaration();
2922
                state.allowIn = true;
2923
2924
                if (init.declarations.length === 1 && matchKeyword('in')) {
2925
                    lex();
2926
                    left = init;
2927
                    right = parseExpression();
2928
                    init = null;
2929
                }
2930
            } else {
2931
                state.allowIn = false;
2932
                init = parseExpression();
2933
                state.allowIn = true;
2934
2935
                if (matchKeyword('in')) {
2936
                    // LeftHandSideExpression
2937
                    if (!isLeftHandSide(init)) {
2938
                        throwErrorTolerant({}, Messages.InvalidLHSInForIn);
2939
                    }
2940
2941
                    lex();
2942
                    left = init;
2943
                    right = parseExpression();
2944
                    init = null;
2945
                }
2946
            }
2947
2948
            if (typeof left === 'undefined') {
2949
                expect(';');
2950
            }
2951
        }
2952
2953
        if (typeof left === 'undefined') {
2954
2955
            if (!match(';')) {
2956
                test = parseExpression();
2957
            }
2958
            expect(';');
2959
2960
            if (!match(')')) {
2961
                update = parseExpression();
2962
            }
2963
        }
2964
2965
        // mamacdon 853a9865
2966
        //expect(')');
2967
        expectConditionCloseParenWrapThrow();
2968
2969
        oldInIteration = state.inIteration;
2970
        state.inIteration = true;
2971
2972
        body = parseStatement();
2973
2974
        state.inIteration = oldInIteration;
2975
2976
        return (typeof left === 'undefined') ?
2977
                delegate.createForStatement(init, test, update, body) :
2978
                delegate.createForInStatement(left, right, body);
2979
    }
2980
2981
    // 12.7 The continue statement
2982
2983
    function parseContinueStatement() {
2984
        var label = null, key;
2985
2986
        expectKeyword('continue');
2987
2988
        // Optimize the most common form: 'continue;'.
2989
        if (source.charCodeAt(index) === 59) {
2990
            lex();
2991
2992
            if (!state.inIteration) {
2993
                throwError({}, Messages.IllegalContinue);
2994
            }
2995
2996
            return delegate.createContinueStatement(null);
2997
        }
2998
2999
        if (peekLineTerminator()) {
3000
            if (!state.inIteration) {
3001
                throwError({}, Messages.IllegalContinue);
3002
            }
3003
3004
            return delegate.createContinueStatement(null);
3005
        }
3006
3007
        if (lookahead.type === Token.Identifier) {
3008
            label = parseVariableIdentifier();
3009
3010
            key = '$' + label.name;
3011
            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
3012
                throwError({}, Messages.UnknownLabel, label.name);
3013
            }
3014
        }
3015
3016
        consumeSemicolon();
3017
3018
        if (label === null && !state.inIteration) {
3019
            throwError({}, Messages.IllegalContinue);
3020
        }
3021
3022
        return delegate.createContinueStatement(label);
3023
    }
3024
3025
    // 12.8 The break statement
3026
3027
    function parseBreakStatement() {
3028
        var label = null, key;
3029
3030
        expectKeyword('break');
3031
3032
        // Catch the very common case first: immediately a semicolon (char #59).
3033
        if (source.charCodeAt(index) === 59) {
3034
            lex();
3035
3036
            if (!(state.inIteration || state.inSwitch)) {
3037
                throwError({}, Messages.IllegalBreak);
3038
            }
3039
3040
            return delegate.createBreakStatement(null);
3041
        }
3042
3043
        if (peekLineTerminator()) {
3044
            if (!(state.inIteration || state.inSwitch)) {
3045
                throwError({}, Messages.IllegalBreak);
3046
            }
3047
3048
            return delegate.createBreakStatement(null);
3049
        }
3050
3051
        if (lookahead.type === Token.Identifier) {
3052
            label = parseVariableIdentifier();
3053
3054
            key = '$' + label.name;
3055
            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
3056
                throwError({}, Messages.UnknownLabel, label.name);
3057
            }
3058
        }
3059
3060
        consumeSemicolon();
3061
3062
        if (label === null && !(state.inIteration || state.inSwitch)) {
3063
            throwError({}, Messages.IllegalBreak);
3064
        }
3065
3066
        return delegate.createBreakStatement(label);
3067
    }
3068
3069
    // 12.9 The return statement
3070
3071
    function parseReturnStatement() {
3072
        var argument = null;
3073
3074
        expectKeyword('return');
3075
3076
        if (!state.inFunctionBody) {
3077
            throwErrorTolerant({}, Messages.IllegalReturn);
3078
        }
3079
3080
        // 'return' followed by a space and an identifier is very common.
3081
        if (source.charCodeAt(index) === 32) {
3082
            if (isIdentifierStart(source.charCodeAt(index + 1))) {
3083
                argument = parseExpression();
3084
                consumeSemicolon();
3085
                return delegate.createReturnStatement(argument);
3086
            }
3087
        }
3088
3089
        if (peekLineTerminator()) {
3090
            return delegate.createReturnStatement(null);
3091
        }
3092
3093
        if (!match(';')) {
3094
            if (!match('}') && lookahead.type !== Token.EOF) {
3095
                argument = parseExpression();
3096
            }
3097
        }
3098
3099
        consumeSemicolon();
3100
3101
        return delegate.createReturnStatement(argument);
3102
    }
3103
3104
    // 12.10 The with statement
3105
3106
    function parseWithStatement() {
3107
        var object, body;
3108
3109
        if (strict) {
3110
            throwErrorTolerant({}, Messages.StrictModeWith);
3111
        }
3112
3113
        expectKeyword('with');
3114
3115
        expect('(');
3116
3117
        object = parseExpression();
3118
3119
        expect(')');
3120
3121
        body = parseStatement();
3122
3123
        return delegate.createWithStatement(object, body);
3124
    }
3125
3126
    // 12.10 The swith statement
3127
3128
    function parseSwitchCase() {
3129
        var test,
3130
            consequent = [],
3131
            statement;
3132
3133
        skipComment();
3134
        delegate.markStart();
3135
        if (matchKeyword('default')) {
3136
            lex();
3137
            test = null;
3138
        } else {
3139
            expectKeyword('case');
3140
            test = parseExpression();
3141
        }
3142
        expect(':');
3143
3144
        while (index < length) {
3145
            if (match('}') || matchKeyword('default') || matchKeyword('case')) {
3146
                break;
3147
            }
3148
            statement = parseStatement();
3149
            consequent.push(statement);
3150
        }
3151
3152
        return delegate.markEnd(delegate.createSwitchCase(test, consequent));
3153
    }
3154
3155
    function parseSwitchStatement() {
3156
        var discriminant, cases, clause, oldInSwitch, defaultFound;
3157
3158
        expectKeyword('switch');
3159
3160
        expect('(');
3161
3162
        discriminant = parseExpression();
3163
3164
        expect(')');
3165
3166
        expect('{');
3167
3168
        cases = [];
3169
3170
        if (match('}')) {
3171
            lex();
3172
            return delegate.createSwitchStatement(discriminant, cases);
3173
        }
3174
3175
        oldInSwitch = state.inSwitch;
3176
        state.inSwitch = true;
3177
        defaultFound = false;
3178
3179
        while (index < length) {
3180
            if (match('}')) {
3181
                break;
3182
            }
3183
            clause = parseSwitchCase();
3184
            if (clause.test === null) {
3185
                if (defaultFound) {
3186
                    throwError({}, Messages.MultipleDefaultsInSwitch);
3187
                }
3188
                defaultFound = true;
3189
            }
3190
            cases.push(clause);
3191
        }
3192
3193
        state.inSwitch = oldInSwitch;
3194
3195
        expect('}');
3196
3197
        return delegate.createSwitchStatement(discriminant, cases);
3198
    }
3199
3200
    // 12.13 The throw statement
3201
3202
    function parseThrowStatement() {
3203
        var argument;
3204
3205
        expectKeyword('throw');
3206
3207
        if (peekLineTerminator()) {
3208
            throwError({}, Messages.NewlineAfterThrow);
3209
        }
3210
3211
        argument = parseExpression();
3212
3213
        consumeSemicolon();
3214
3215
        return delegate.createThrowStatement(argument);
3216
    }
3217
3218
    // 12.14 The try statement
3219
3220
    function parseCatchClause() {
3221
        var param, body;
3222
3223
        skipComment();
3224
        delegate.markStart();
3225
        expectKeyword('catch');
3226
3227
        expect('(');
3228
        if (match(')')) {
3229
            throwUnexpected(lookahead);
3230
        }
3231
3232
        param = parseVariableIdentifier();
3233
        // 12.14.1
3234
        if (strict && isRestrictedWord(param.name)) {
3235
            throwErrorTolerant({}, Messages.StrictCatchVariable);
3236
        }
3237
3238
        expect(')');
3239
        body = parseBlock();
3240
        return delegate.markEnd(delegate.createCatchClause(param, body));
3241
    }
3242
3243
    function parseTryStatement() {
3244
        var block, handlers = [], finalizer = null;
3245
3246
        expectKeyword('try');
3247
3248
        block = parseBlock();
3249
3250
        if (matchKeyword('catch')) {
3251
            handlers.push(parseCatchClause());
3252
        }
3253
3254
        if (matchKeyword('finally')) {
3255
            lex();
3256
            finalizer = parseBlock();
3257
        }
3258
3259
        if (handlers.length === 0 && !finalizer) {
3260
            throwError({}, Messages.NoCatchOrFinally);
3261
        }
3262
3263
        return delegate.createTryStatement(block, [], handlers, finalizer);
3264
    }
3265
3266
    // 12.15 The debugger statement
3267
3268
    function parseDebuggerStatement() {
3269
        expectKeyword('debugger');
3270
3271
        consumeSemicolon();
3272
3273
        return delegate.createDebuggerStatement();
3274
    }
3275
3276
    // 12 Statements
3277
3278
    function parseStatement() {
3279
        var type = lookahead.type,
3280
            expr,
3281
            labeledBody,
3282
            key;
3283
3284
        if (type === Token.EOF) {
3285
            throwUnexpected(lookahead);
3286
        }
3287
3288
        skipComment();
3289
        delegate.markStart();
3290
3291
        if (type === Token.Punctuator) {
3292
            switch (lookahead.value) {
3293
            case ';':
3294
                return delegate.markEnd(parseEmptyStatement());
3295
            case '{':
3296
                return delegate.markEnd(parseBlock());
3297
            case '(':
3298
                return delegate.markEnd(parseExpressionStatement());
3299
            default:
3300
                break;
3301
            }
3302
        }
3303
3304
        if (type === Token.Keyword) {
3305
            switch (lookahead.value) {
3306
            case 'break':
3307
                return delegate.markEnd(parseBreakStatement());
3308
            case 'continue':
3309
                return delegate.markEnd(parseContinueStatement());
3310
            case 'debugger':
3311
                return delegate.markEnd(parseDebuggerStatement());
3312
            case 'do':
3313
                return delegate.markEnd(parseDoWhileStatement());
3314
            case 'for':
3315
                return delegate.markEnd(parseForStatement());
3316
            case 'function':
3317
                return delegate.markEnd(parseFunctionDeclaration());
3318
            case 'if':
3319
                return delegate.markEnd(parseIfStatement());
3320
            case 'return':
3321
                return delegate.markEnd(parseReturnStatement());
3322
            case 'switch':
3323
                return delegate.markEnd(parseSwitchStatement());
3324
            case 'throw':
3325
                return delegate.markEnd(parseThrowStatement());
3326
            case 'try':
3327
                return delegate.markEnd(parseTryStatement());
3328
            case 'var':
3329
                return delegate.markEnd(parseVariableStatement());
3330
            case 'while':
3331
                return delegate.markEnd(parseWhileStatement());
3332
            case 'with':
3333
                return delegate.markEnd(parseWithStatement());
3334
            default:
3335
                break;
3336
            }
3337
        }
3338
3339
        expr = parseExpression();
3340
3341
        // 12.12 Labelled Statements
3342
        if (expr && (expr.type === Syntax.Identifier) && match(':')) { // mamacdon 1420b19
3343
            lex();
3344
3345
            key = '$' + expr.name;
3346
            if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
3347
                throwError({}, Messages.Redeclaration, 'Label', expr.name);
3348
            }
3349
3350
            state.labelSet[key] = true;
3351
            labeledBody = parseStatement();
3352
            delete state.labelSet[key];
3353
            return delegate.markEnd(delegate.createLabeledStatement(expr, labeledBody));
3354
        }
3355
3356
        consumeSemicolon();
3357
3358
        return delegate.markEnd(delegate.createExpressionStatement(expr));
3359
    }
3360
3361
    // 13 Function Definition
3362
3363
    function parseFunctionSourceElements() {
3364
        var sourceElement, sourceElements = [], token, directive, firstRestricted,
3365
            oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody;
3366
3367
        skipComment();
3368
        delegate.markStart();
3369
        expect('{');
3370
3371
        while (index < length) {
3372
            if (lookahead.type !== Token.StringLiteral) {
3373
                break;
3374
            }
3375
            token = lookahead;
3376
3377
            sourceElement = parseSourceElement();
3378
            sourceElements.push(sourceElement);
3379
            if (sourceElement.expression.type !== Syntax.Literal) {
3380
                // this is not directive
3381
                break;
3382
            }
3383
            directive = source.slice(token.range[0] + 1, token.range[1] - 1);
3384
            if (directive === 'use strict') {
3385
                strict = true;
3386
                if (firstRestricted) {
3387
                    throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
3388
                }
3389
            } else {
3390
                if (!firstRestricted && token.octal) {
3391
                    firstRestricted = token;
3392
                }
3393
            }
3394
        }
3395
3396
        oldLabelSet = state.labelSet;
3397
        oldInIteration = state.inIteration;
3398
        oldInSwitch = state.inSwitch;
3399
        oldInFunctionBody = state.inFunctionBody;
3400
3401
        state.labelSet = {};
3402
        state.inIteration = false;
3403
        state.inSwitch = false;
3404
        state.inFunctionBody = true;
3405
3406
        while (index < length) {
3407
            if (match('}')) {
3408
                break;
3409
            }
3410
            sourceElement = parseSourceElement();
3411
            if (typeof sourceElement === 'undefined') {
3412
                break;
3413
            }
3414
            sourceElements.push(sourceElement);
3415
        }
3416
3417
        // mamacdon 853a986
3418
        //expect('}');
3419
        expectConditionCloseBracketWrapThrow();
3420
3421
        state.labelSet = oldLabelSet;
3422
        state.inIteration = oldInIteration;
3423
        state.inSwitch = oldInSwitch;
3424
        state.inFunctionBody = oldInFunctionBody;
3425
3426
        return delegate.markEnd(delegate.createBlockStatement(sourceElements));
3427
    }
3428
3429
    function parseParams(firstRestricted) {
3430
        var param, params = [], token, stricted, paramSet, key, message;
3431
        expect('(');
3432
3433
        if (!match(')')) {
3434
            paramSet = {};
3435
            while (index < length) {
3436
                token = lookahead;
3437
                param = parseVariableIdentifier();
3438
                key = '$' + token.value;
3439
                if (strict) {
3440
                    if (isRestrictedWord(token.value)) {
3441
                        stricted = token;
3442
                        message = Messages.StrictParamName;
3443
                    }
3444
                    if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
3445
                        stricted = token;
3446
                        message = Messages.StrictParamDupe;
3447
                    }
3448
                } else if (!firstRestricted) {
3449
                    if (isRestrictedWord(token.value)) {
3450
                        firstRestricted = token;
3451
                        message = Messages.StrictParamName;
3452
                    } else if (isStrictModeReservedWord(token.value)) {
3453
                        firstRestricted = token;
3454
                        message = Messages.StrictReservedWord;
3455
                    } else if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
3456
                        firstRestricted = token;
3457
                        message = Messages.StrictParamDupe;
3458
                    }
3459
                }
3460
                params.push(param);
3461
                paramSet[key] = true;
3462
                if (match(')')) {
3463
                    break;
3464
                }
3465
                expect(',');
3466
            }
3467
        }
3468
3469
        expect(')');
3470
3471
        return {
3472
            params: params,
3473
            stricted: stricted,
3474
            firstRestricted: firstRestricted,
3475
            message: message
3476
        };
3477
    }
3478
3479
    function parseFunctionDeclaration() {
3480
        var id, params = [], body, token, stricted, tmp, firstRestricted, message, previousStrict;
3481
3482
        skipComment();
3483
        delegate.markStart();
3484
3485
        expectKeyword('function');
3486
        token = lookahead;
3487
        id = parseVariableIdentifier();
3488
        if (strict) {
3489
            if (isRestrictedWord(token.value)) {
3490
                throwErrorTolerant(token, Messages.StrictFunctionName);
3491
            }
3492
        } else {
3493
            if (isRestrictedWord(token.value)) {
3494
                firstRestricted = token;
3495
                message = Messages.StrictFunctionName;
3496
            } else if (isStrictModeReservedWord(token.value)) {
3497
                firstRestricted = token;
3498
                message = Messages.StrictReservedWord;
3499
            }
3500
        }
3501
3502
        tmp = parseParams(firstRestricted);
3503
        params = tmp.params;
3504
        stricted = tmp.stricted;
3505
        firstRestricted = tmp.firstRestricted;
3506
        if (tmp.message) {
3507
            message = tmp.message;
3508
        }
3509
3510
        previousStrict = strict;
3511
        body = parseFunctionSourceElements();
3512
        if (strict && firstRestricted) {
3513
            throwError(firstRestricted, message);
3514
        }
3515
        if (strict && stricted) {
3516
            throwErrorTolerant(stricted, message);
3517
        }
3518
        strict = previousStrict;
3519
3520
        return delegate.markEnd(delegate.createFunctionDeclaration(id, params, [], body));
3521
    }
3522
3523
    function parseFunctionExpression() {
3524
        var token, id = null, stricted, firstRestricted, message, tmp, params = [], body, previousStrict;
3525
3526
        delegate.markStart();
3527
        expectKeyword('function');
3528
3529
        if (!match('(')) {
3530
            token = lookahead;
3531
            id = parseVariableIdentifier();
3532
            if (strict) {
3533
                if (isRestrictedWord(token.value)) {
3534
                    throwErrorTolerant(token, Messages.StrictFunctionName);
3535
                }
3536
            } else {
3537
                if (isRestrictedWord(token.value)) {
3538
                    firstRestricted = token;
3539
                    message = Messages.StrictFunctionName;
3540
                } else if (isStrictModeReservedWord(token.value)) {
3541
                    firstRestricted = token;
3542
                    message = Messages.StrictReservedWord;
3543
                }
3544
            }
3545
        }
3546
3547
        tmp = parseParams(firstRestricted);
3548
        params = tmp.params;
3549
        stricted = tmp.stricted;
3550
        firstRestricted = tmp.firstRestricted;
3551
        if (tmp.message) {
3552
            message = tmp.message;
3553
        }
3554
3555
        previousStrict = strict;
3556
        body = parseFunctionSourceElements();
3557
        if (strict && firstRestricted) {
3558
            throwError(firstRestricted, message);
3559
        }
3560
        if (strict && stricted) {
3561
            throwErrorTolerant(stricted, message);
3562
        }
3563
        strict = previousStrict;
3564
3565
        return delegate.markEnd(delegate.createFunctionExpression(id, params, [], body));
3566
    }
3567
3568
    // 14 Program
3569
3570
    function parseSourceElement() {
3571
        if (lookahead.type === Token.Keyword) {
3572
            switch (lookahead.value) {
3573
            case 'const':
3574
            case 'let':
3575
                return parseConstLetDeclaration(lookahead.value);
3576
            case 'function':
3577
                return parseFunctionDeclaration();
3578
            default:
3579
                return parseStatement();
3580
            }
3581
        }
3582
3583
        if (lookahead.type !== Token.EOF) {
3584
            return parseStatement();
3585
        }
3586
    }
3587
3588
    function parseSourceElements() {
3589
        var sourceElement, sourceElements = [], token, directive, firstRestricted;
3590
3591
        while (index < length) {
3592
            token = lookahead;
3593
            if (token.type !== Token.StringLiteral) {
3594
                break;
3595
            }
3596
3597
            sourceElement = parseSourceElement();
3598
            sourceElements.push(sourceElement);
3599
            if (sourceElement.expression.type !== Syntax.Literal) {
3600
                // this is not directive
3601
                break;
3602
            }
3603
            directive = source.slice(token.range[0] + 1, token.range[1] - 1);
3604
            if (directive === 'use strict') {
3605
                strict = true;
3606
                if (firstRestricted) {
3607
                    throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
3608
                }
3609
            } else {
3610
                if (!firstRestricted && token.octal) {
3611
                    firstRestricted = token;
3612
                }
3613
            }
3614
        }
3615
3616
        while (index < length) {
3617
            sourceElement = parseSourceElement();
3618
            if (typeof sourceElement === 'undefined') {
3619
                break;
3620
            }
3621
            sourceElements.push(sourceElement);
3622
        }
3623
        return sourceElements;
3624
    }
3625
3626
    function parseProgram() {
3627
        var body;
3628
3629
        skipComment();
3630
        delegate.markStart();
3631
        strict = false;
3632
        peek();
3633
        body = parseSourceElements();
3634
        return delegate.markEnd(delegate.createProgram(body));
3635
    }
3636
3637
    function attachComments() {
3638
        var i, attacher, comment, leading, trailing;
3639
3640
        for (i = 0; i < extra.pendingComments.length; ++i) {
3641
            attacher = extra.pendingComments[i];
3642
            comment = attacher.comment;
3643
            leading = attacher.leading;
3644
            if (leading) {
3645
                if (typeof leading.leadingComments === 'undefined') {
3646
                    leading.leadingComments = [];
3647
                }
3648
                leading.leadingComments.push(attacher.comment);
3649
            }
3650
            trailing = attacher.trailing;
3651
            if (trailing) {
3652
                if (typeof trailing.trailingComments === 'undefined') {
3653
                    trailing.trailingComments = [];
3654
                }
3655
                trailing.trailingComments.push(attacher.comment);
3656
            }
3657
        }
3658
        extra.pendingComments = [];
3659
    }
3660
3661
    function filterTokenLocation() {
3662
        var i, entry, token, tokens = [];
3663
3664
        for (i = 0; i < extra.tokens.length; ++i) {
3665
            entry = extra.tokens[i];
3666
            token = {
3667
                type: entry.type,
3668
                value: entry.value
3669
            };
3670
            if (extra.range) {
3671
                token.range = entry.range;
3672
            }
3673
            if (extra.loc) {
3674
                token.loc = entry.loc;
3675
            }
3676
            tokens.push(token);
3677
        }
3678
3679
        extra.tokens = tokens;
3680
    }
3681
3682
    function LocationMarker() {
3683
        this.marker = [index, lineNumber, index - lineStart, 0, 0, 0];
3684
    }
3685
3686
    LocationMarker.prototype = {
3687
        constructor: LocationMarker,
3688
3689
        end: function () {
3690
            this.marker[3] = index;
3691
            this.marker[4] = lineNumber;
3692
            this.marker[5] = index - lineStart;
3693
        },
3694
3695
        apply: function (node) {
3696
            if (extra.range) {
3697
                node.range = [this.marker[0], this.marker[3]];
3698
            }
3699
            if (extra.loc) {
3700
                node.loc = {
3701
                    start: {
3702
                        line: this.marker[1],
3703
                        column: this.marker[2]
3704
                    },
3705
                    end: {
3706
                        line: this.marker[4],
3707
                        column: this.marker[5]
3708
                    }
3709
                };
3710
                node = delegate.postProcess(node);
3711
            }
3712
            if (extra.attachComment) {
3713
                delegate.processComment(node);
3714
            }
3715
        }
3716
    };
3717
3718
    function createLocationMarker() {
3719
        if (!extra.loc && !extra.range) {
3720
            return null;
3721
        }
3722
3723
        skipComment();
3724
3725
        return new LocationMarker();
3726
    }
3727
3728
    function tokenize(code, options) {
3729
        var toString,
3730
            token,
3731
            tokens;
3732
3733
        toString = String;
3734
        if (typeof code !== 'string' && !(code instanceof String)) {
3735
            code = toString(code);
3736
        }
3737
3738
        delegate = SyntaxTreeDelegate;
3739
        source = code;
3740
        index = 0;
3741
        lineNumber = (source.length > 0) ? 1 : 0;
3742
        lineStart = 0;
3743
        length = source.length;
3744
        lookahead = null;
3745
        state = {
3746
            allowIn: true,
3747
            labelSet: {},
3748
            inFunctionBody: false,
3749
            inIteration: false,
3750
            inSwitch: false,
3751
            lastCommentStart: -1
3752
        };
3753
3754
        extra = {};
3755
3756
        // Options matching.
3757
        options = options || {};
3758
3759
        // Of course we collect tokens here.
3760
        options.tokens = true;
3761
        extra.tokens = [];
3762
        extra.tokenize = true;
3763
        // The following two fields are necessary to compute the Regex tokens.
3764
        extra.openParenToken = -1;
3765
        extra.openCurlyToken = -1;
3766
3767
        extra.range = (typeof options.range === 'boolean') && options.range;
3768
        extra.loc = (typeof options.loc === 'boolean') && options.loc;
3769
3770
        if (typeof options.comment === 'boolean' && options.comment) {
3771
            extra.comments = [];
3772
        }
3773
        if (typeof options.tolerant === 'boolean' && options.tolerant) {
3774
            extra.errors = [];
3775
        }
3776
3777
        if (length > 0) {
3778
            if (typeof source[0] === 'undefined') {
3779
                // Try first to convert to a string. This is good as fast path
3780
                // for old IE which understands string indexing for string
3781
                // literals only and not for string object.
3782
                if (code instanceof String) {
3783
                    source = code.valueOf();
3784
                }
3785
            }
3786
        }
3787
3788
        try {
3789
            peek();
3790
            if (lookahead.type === Token.EOF) {
3791
                return extra.tokens;
3792
            }
3793
3794
            token = lex();
3795
            while (lookahead.type !== Token.EOF) {
3796
                try {
3797
                    token = lex();
3798
                } catch (lexError) {
3799
                    token = lookahead;
3800
                    if (extra.errors) {
3801
                        extra.errors.push(lexError);
3802
                        // We have to break on the first error
3803
                        // to avoid infinite loops.
3804
                        break;
3805
                    } else {
3806
                        throw lexError;
3807
                    }
3808
                }
3809
            }
3810
3811
            filterTokenLocation();
3812
            tokens = extra.tokens;
3813
            if (typeof extra.comments !== 'undefined') {
3814
                tokens.comments = extra.comments;
3815
            }
3816
            if (typeof extra.errors !== 'undefined') {
3817
                tokens.errors = extra.errors;
3818
            }
3819
        } catch (e) {
3820
            throw e;
3821
        } finally {
3822
            extra = {};
3823
        }
3824
        return tokens;
3825
    }
3826
3827
    function parse(code, options) {
3828
        var program, toString;
3829
3830
        toString = String;
3831
        if (typeof code !== 'string' && !(code instanceof String)) {
3832
            code = toString(code);
3833
        }
3834
3835
        delegate = SyntaxTreeDelegate;
3836
        source = code;
3837
        index = 0;
3838
        lineNumber = (source.length > 0) ? 1 : 0;
3839
        lineStart = 0;
3840
        length = source.length;
3841
        lookahead = null;
3842
        state = {
3843
            allowIn: true,
3844
            labelSet: {},
3845
            inFunctionBody: false,
3846
            inIteration: false,
3847
            inSwitch: false,
3848
            lastCommentStart: -1,
3849
            markerStack: []
3850
        };
3851
3852
        extra = {};
3853
        if (typeof options !== 'undefined') {
3854
            extra.range = (typeof options.range === 'boolean') && options.range;
3855
            extra.loc = (typeof options.loc === 'boolean') && options.loc;
3856
            extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment;
3857
3858
            if (extra.loc && options.source !== null && options.source !== undefined) {
3859
                extra.source = toString(options.source);
3860
            }
3861
3862
            if (typeof options.tokens === 'boolean' && options.tokens) {
3863
                extra.tokens = [];
3864
            }
3865
            if (typeof options.comment === 'boolean' && options.comment) {
3866
                extra.comments = [];
3867
            }
3868
            if (typeof options.tolerant === 'boolean' && options.tolerant) {
3869
                extra.errors = [];
3870
3871
				// mamacdon patch
3872
				extra.parseStatement = parseStatement;
3873
				extra.parseExpression = parseExpression;
3874
				extra.parseNonComputedProperty = parseNonComputedProperty;
3875
				extra.consumeSemicolon = consumeSemicolon;
3876
3877
				parseStatement = wrapThrowParseStatement(parseStatement);       // Note special case
3878
				parseExpression = wrapThrow(parseExpression);
3879
				// this enables 'foo.<EOF>' to return something
3880
				parseNonComputedProperty = wrapThrow(parseNonComputedProperty);
3881
				consumeSemicolon = wrapThrow(consumeSemicolon);
3882
            }
3883
            if (extra.attachComment) {
3884
                extra.range = true;
3885
                extra.pendingComments = [];
3886
                extra.comments = [];
3887
            }
3888
        }
3889
3890
        if (length > 0) {
3891
            if (typeof source[0] === 'undefined') {
3892
                // Try first to convert to a string. This is good as fast path
3893
                // for old IE which understands string indexing for string
3894
                // literals only and not for string object.
3895
                if (code instanceof String) {
3896
                    source = code.valueOf();
3897
                }
3898
            }
3899
        }
3900
3901
        try {
3902
            program = parseProgram();
3903
            if (typeof extra.comments !== 'undefined') {
3904
                program.comments = extra.comments;
3905
            }
3906
            if (typeof extra.tokens !== 'undefined') {
3907
                filterTokenLocation();
3908
                program.tokens = extra.tokens;
3909
            }
3910
            if (typeof extra.errors !== 'undefined') {
3911
                program.errors = extra.errors;
3912
            }
3913
            if (extra.attachComment) {
3914
                attachComments();
3915
            }
3916
        } catch (e) {
3917
            throw e;
3918
        } finally {
3919
			// mamacdon unpatch
3920
			parseStatement = extra.parseStatement;
3921
			parseExpression = extra.parseExpression;
3922
			parseNonComputedProperty = extra.parseNonComputedProperty;
3923
			consumeSemicolon = extra.consumeSemicolon;
3924
3925
            extra = {};
3926
        }
3927
3928
        return program;
3929
    }
3930
3931
	/**
3932
	 * @name expectConditionCloseBracketWrapThrow
3933
	 * @description Gracefully handles a missing '}' if the mode is set to tolerant
3934
	 * @function
3935
	 * @private
3936
	 * @since 5.0
3937
	 */
3938
	function expectConditionCloseBracketWrapThrow() {
3939
		if (extra.errors) {
3940
			// continue parsing even with missing close
3941
			// brace.  This gives a better AST for the
3942
			// block, as information about
3943
			// the parsed statements remain
3944
			try {
3945
				expect('}');
3946
			} catch (e) {
3947
				pushError(e);
3948
	        }
3949
		} else {
3950
			expect('}');
3951
		}
3952
	}
3953
3954
	/**
3955
	 * @name expectConditionCloseParenWrapThrow
3956
	 * @description For statements like if, while, for, etc. check for the ')' on the condition. If
3957
	 * it is not present, catch the error, and backtrack if we see a '{' instead (to continue parsing the block)
3958
	 * @function
3959
	 * @private
3960
	 * @throws The original error from  trying to consume the ')' char if not in tolerant mode
3961
	 * @since 5.0
3962
	 */
3963
	function expectConditionCloseParenWrapThrow() {
3964
        // needs generalizing to a 'expect A but don't consume if you hit B or C'
3965
        try {
3966
            expect(')');
3967
        } catch (e) {
3968
            if (extra.errors) {
3969
	            pushError(e);
3970
	            // If a { was hit instead of a ) then don't consume it, let us assume a ')' was 
3971
	            // missed and the consequent block is OK
3972
	            if (source[e.index] === '{') {
3973
	              index=e.index;
3974
	              lookahead = null;
3975
	            // activating this block will mean the following statement is parsed as a consequent / body.
3976
	            // without it the statement is considered not at all part of the enclosing statement at all
3977
	            //} else {
3978
	            //  rewind();
3979
	            }
3980
            } else {
3981
                throw e;
3982
            }
3983
        }
3984
	}
3985
    // mamacdon 1420b19
3986
    // @ 1.0.0 esprima.js:1609
3987
	/**
3988
	 * @name pushError
3989
     * @description Add the error if not already reported.
3990
     * @function
3991
     * @private
3992
     * @param {Object} error The error object to push
3993
     * @since 5.0
3994
     */
3995
    function pushError(error) {
3996
        var len = extra.errors.length;
3997
        for (var e=0; e < len; e++) {
3998
            var existingError = extra.errors[e];
3999
            if (existingError.index === error.index && existingError.message === error.message) {
4000
                return; // do not add duplicate
4001
            }
4002
        }
4003
        extra.errors.push(error);
4004
    }
1660
    
4005
    
1661
    // TODO refactor
4006
    //Recovery
4007
    function wrapThrow(parseFunction) {
4008
        return function () {
4009
            try {
4010
            	var initialHeight = state.markerStack.length;
4011
                return parseFunction.apply(null, arguments);
4012
            } catch (e) {
4013
				pushError(e);
4014
				// Clean up un-popped end markers from failed parse
4015
				while (state.markerStack.length > initialHeight)
4016
					delegate.markEndIf(null);
4017
				return null;
4018
            }
4019
        };
4020
    }
4021
    
4022
    function wrapThrowParseStatement(parseFunction) {
4023
        return function () {
4024
            extra.statementStart = index; // record where attempting to parse statement from
4025
            try {
4026
                return parseFunction.apply(null, arguments);
4027
            } catch (e) {
4028
				pushError(e);
4029
//				return null;   // why is this commented out
4030
            }
4031
        };
4032
    }
4033
1662
    /**
4034
    /**
1663
     * From a position 'idx' in the source this function moves back through the source until
4035
     * @name isNewlineOrSemicolon
4036
     * @description If the given char is the new line char or a semicolon char
4037
     * @function
4038
     * @private
4039
     * @param {String} ch The character to check
4040
     * @returns {Boolean} <code>true</code> if the char is a new line or semicolon <code>false</code> otherwise
4041
     * @since 5.0
4042
     */
4043
    function isNewlineOrSemicolon(ch) {
4044
      return ch===';' || ch==='\n';
4045
    }
4046
    
4047
    /**
4048
     * @name rewind
4049
     * @descripton Rewind the lex position to the most recent newline or semicolon.  If that turns out
4050
     * to be the same position as the most recent parsing of a statement was attempted at, 
4051
     * don't rewind (because it will fail in the same way).  If it turns out to be the same
4052
     * position as where we last rewound to, don't do it.  Clears the buffer and sets the
4053
     * index in order to continue lexing from the new position.
4054
     * @function
4055
     * @private
4056
     * @since 5.0
4057
     */
4058
    function rewind() {
4059
        var idx = index;
4060
        while (idx>0 && !isNewlineOrSemicolon(source[idx])) {
4061
            idx--;
4062
        }
4063
        if (idx<=extra.statementStart) {
4064
            return;
4065
        }
4066
        var doRewind = false;
4067
        if (extra.lastRewindLocation) {
4068
            doRewind = true;
4069
        } else {
4070
            var v = extra.lastRewindLocation;
4071
            if (v!==idx) {
4072
              doRewind=true;
4073
            }
4074
        }	        
4075
        if (doRewind) {
4076
	        index = idx;
4077
	        peek(); // recalculate lookahead
4078
	        extra.lastRewindLocation = index;
4079
        }
4080
    }
4081
4082
    // mamacdon 1420b19
4083
    // @ 1.0.0 esprima.js:1661
4084
    // TODO refactor
4085
	/**
4086
	 * @name rewindToInterestingChar
4087
     * @description From a position 'idx' in the source this function moves back through the source until
1664
     * it finds a non-whitespace (including newlines) character.  It will jump over block comments.
4088
     * it finds a non-whitespace (including newlines) character.  It will jump over block comments.
1665
     * Returns an object with properties: index - the index it rewound to.  lineChange - boolean indicating
4089
     * Returns an object with properties: index - the index it rewound to.  lineChange - boolean indicating
1666
     * if a line was crossed during rewind.
4090
     * if a line was crossed during rewind.
4091
     * @function
4092
     * @private
4093
     * @param {Number} idx The index to rewind to
4094
     * @returns {Object} Returns the object with the index and line change to rewind to
4095
     * @since 5.0
1667
     */
4096
     */
1668
    function rewindToInterestingChar(idx) {
4097
    function rewindToInterestingChar(idx) {
1669
        var done = false;
4098
        var done = false;
Lines 1708-1719 Link Here
1708
    }
4137
    }
1709
    
4138
    
1710
    /**
4139
    /**
1711
     * When a problem occurs in parseNonComputedProperty, attempt to reposition 
4140
     * @name attemptRecoveryNonComputedProperty
4141
     * @description When a problem occurs in parseNonComputedProperty, attempt to reposition 
1712
     * the lexer to continue processing.
4142
     * the lexer to continue processing.
1713
     * Example: '(foo.)' we will hit the ')' instead of discovering a property and consuming the ')'
4143
     * Example: '(foo.)' we will hit the ')' instead of discovering a property and consuming the ')'
1714
     * will cause the parse of the paretheses to fail, so 'unconsume' it.
4144
     * will cause the parse of the paretheses to fail, so 'unconsume' it.
1715
     * Basically rewind by one token if punctuation (type 7) is hit and the char before it was
4145
     * Basically rewind by one token if punctuation (type 7) is hit and the char before it was
1716
     * a dot.  This will enable the enclosing parse rule to consume the punctuation.
4146
     * a dot.  This will enable the enclosing parse rule to consume the punctuation.
4147
     * @function
4148
     * @private
4149
     * @param {String} token The token to try and recover from
4150
     * @since 5.0
1717
     */
4151
     */
1718
    function attemptRecoveryNonComputedProperty(token) {
4152
    function attemptRecoveryNonComputedProperty(token) {
1719
        if (token.value && token.type===Token.Punctuator) {
4153
        if (token.value && token.type===Token.Punctuator) {
Lines 1727-3799 Link Here
1727
                // do not recover in this case
4161
                // do not recover in this case
1728
            } else if (ch==='.') {
4162
            } else if (ch==='.') {
1729
	            index = idx+1;
4163
	            index = idx+1;
1730
	            buffer=null;
4164
//                lookahead=null;
4165
                peek(); // recalculate lookahead
1731
            }
4166
            }
1732
        }
4167
        }
1733
    }
4168
    }
1734
4169
4170
    // Sync with *.json manifests.
4171
    exports.version = '1.1.0-dev';
1735
4172
1736
    function parseNonComputedProperty() {
4173
    exports.tokenize = tokenize;
1737
        var token = lex();
1738
1739
        if (!isIdentifierName(token)) {
1740
            if (extra.errors) {
1741
                attemptRecoveryNonComputedProperty(token);
1742
            }
1743
            throwUnexpected(token);
1744
        }
1745
1746
        return {
1747
            type: Syntax.Identifier,
1748
            name: token.value
1749
        };
1750
    }
1751
1752
    function parseNonComputedMember(object) {
1753
        return {
1754
            type: Syntax.MemberExpression,
1755
            computed: false,
1756
            object: object,
1757
            property: parseNonComputedProperty()
1758
        };
1759
    }
1760
1761
    function parseComputedMember(object) {
1762
        var property, expr;
1763
1764
        expect('[');
1765
        property = parseExpression();
1766
        expr = {
1767
            type: Syntax.MemberExpression,
1768
            computed: true,
1769
            object: object,
1770
            property: property
1771
        };
1772
        expect(']');
1773
        return expr;
1774
    }
1775
1776
    function parseCallMember(object) {
1777
        return {
1778
            type: Syntax.CallExpression,
1779
            callee: object,
1780
            'arguments': parseArguments()
1781
        };
1782
    }
1783
1784
    function parseNewExpression() {
1785
        var expr;
1786
1787
        expectKeyword('new');
1788
1789
        expr = {
1790
            type: Syntax.NewExpression,
1791
            callee: parseLeftHandSideExpression(),
1792
            'arguments': []
1793
        };
1794
1795
        if (match('(')) {
1796
            expr['arguments'] = parseArguments();
1797
        }
1798
1799
        return expr;
1800
    }
1801
1802
    function parseLeftHandSideExpressionAllowCall() {
1803
        var useNew, expr;
1804
1805
        useNew = matchKeyword('new');
1806
        expr = useNew ? parseNewExpression() : parsePrimaryExpression();
1807
1808
        while (index < length) {
1809
            if (match('.')) {
1810
                lex();
1811
                expr = parseNonComputedMember(expr);
1812
            } else if (match('[')) {
1813
                expr = parseComputedMember(expr);
1814
            } else if (match('(')) {
1815
                expr = parseCallMember(expr);
1816
            } else {
1817
                break;
1818
            }
1819
        }
1820
1821
        return expr;
1822
    }
1823
1824
    function parseLeftHandSideExpression() {
1825
        var useNew, expr;
1826
1827
        useNew = matchKeyword('new');
1828
        expr = useNew ? parseNewExpression() : parsePrimaryExpression();
1829
1830
        while (index < length) {
1831
            if (match('.')) {
1832
                lex();
1833
                expr = parseNonComputedMember(expr);
1834
            } else if (match('[')) {
1835
                expr = parseComputedMember(expr);
1836
            } else {
1837
                break;
1838
            }
1839
        }
1840
1841
        return expr;
1842
    }
1843
1844
    // 11.3 Postfix Expressions
1845
1846
    function parsePostfixExpression() {
1847
        var expr = parseLeftHandSideExpressionAllowCall();
1848
1849
        if ((match('++') || match('--')) && !peekLineTerminator()) {
1850
            // 11.3.1, 11.3.2
1851
            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
1852
                throwError({}, Messages.StrictLHSPostfix);
1853
            }
1854
            expr = {
1855
                type: Syntax.UpdateExpression,
1856
                operator: lex().value,
1857
                argument: expr,
1858
                prefix: false
1859
            };
1860
        }
1861
1862
        return expr;
1863
    }
1864
1865
    // 11.4 Unary Operators
1866
1867
    function parseUnaryExpression() {
1868
        var token, expr;
1869
1870
        if (match('++') || match('--')) {
1871
            token = lex();
1872
            expr = parseUnaryExpression();
1873
            // 11.4.4, 11.4.5
1874
            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
1875
                throwError({}, Messages.StrictLHSPrefix);
1876
            }
1877
            expr = {
1878
                type: Syntax.UpdateExpression,
1879
                operator: token.value,
1880
                argument: expr,
1881
                prefix: true
1882
            };
1883
            return expr;
1884
        }
1885
1886
        if (match('+') || match('-') || match('~') || match('!')) {
1887
            expr = {
1888
                type: Syntax.UnaryExpression,
1889
                operator: lex().value,
1890
                argument: parseUnaryExpression()
1891
            };
1892
            return expr;
1893
        }
1894
1895
        if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
1896
            expr = {
1897
                type: Syntax.UnaryExpression,
1898
                operator: lex().value,
1899
                argument: parseUnaryExpression()
1900
            };
1901
            if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
1902
                throwErrorTolerant({}, Messages.StrictDelete);
1903
            }
1904
            return expr;
1905
        }
1906
1907
        return parsePostfixExpression();
1908
    }
1909
1910
    // 11.5 Multiplicative Operators
1911
1912
    function parseMultiplicativeExpression() {
1913
        var expr = parseUnaryExpression();
1914
1915
        while (match('*') || match('/') || match('%')) {
1916
            expr = {
1917
                type: Syntax.BinaryExpression,
1918
                operator: lex().value,
1919
                left: expr,
1920
                right: parseUnaryExpression()
1921
            };
1922
        }
1923
1924
        return expr;
1925
    }
1926
1927
    // 11.6 Additive Operators
1928
1929
    function parseAdditiveExpression() {
1930
        var expr = parseMultiplicativeExpression();
1931
1932
        while (match('+') || match('-')) {
1933
            expr = {
1934
                type: Syntax.BinaryExpression,
1935
                operator: lex().value,
1936
                left: expr,
1937
                right: parseMultiplicativeExpression()
1938
            };
1939
        }
1940
1941
        return expr;
1942
    }
1943
1944
    // 11.7 Bitwise Shift Operators
1945
1946
    function parseShiftExpression() {
1947
        var expr = parseAdditiveExpression();
1948
1949
        while (match('<<') || match('>>') || match('>>>')) {
1950
            expr = {
1951
                type: Syntax.BinaryExpression,
1952
                operator: lex().value,
1953
                left: expr,
1954
                right: parseAdditiveExpression()
1955
            };
1956
        }
1957
1958
        return expr;
1959
    }
1960
    // 11.8 Relational Operators
1961
1962
    function parseRelationalExpression() {
1963
        var expr, previousAllowIn;
1964
1965
        previousAllowIn = state.allowIn;
1966
        state.allowIn = true;
1967
        expr = parseShiftExpression();
1968
        state.allowIn = previousAllowIn;
1969
1970
        if (match('<') || match('>') || match('<=') || match('>=')) {
1971
            expr = {
1972
                type: Syntax.BinaryExpression,
1973
                operator: lex().value,
1974
                left: expr,
1975
                right: parseRelationalExpression()
1976
            };
1977
        } else if (state.allowIn && matchKeyword('in')) {
1978
            lex();
1979
            expr = {
1980
                type: Syntax.BinaryExpression,
1981
                operator: 'in',
1982
                left: expr,
1983
                right: parseRelationalExpression()
1984
            };
1985
        } else if (matchKeyword('instanceof')) {
1986
            lex();
1987
            expr = {
1988
                type: Syntax.BinaryExpression,
1989
                operator: 'instanceof',
1990
                left: expr,
1991
                right: parseRelationalExpression()
1992
            };
1993
        }
1994
1995
        return expr;
1996
    }
1997
1998
    // 11.9 Equality Operators
1999
2000
    function parseEqualityExpression() {
2001
        var expr = parseRelationalExpression();
2002
2003
        while (match('==') || match('!=') || match('===') || match('!==')) {
2004
            expr = {
2005
                type: Syntax.BinaryExpression,
2006
                operator: lex().value,
2007
                left: expr,
2008
                right: parseRelationalExpression()
2009
            };
2010
        }
2011
2012
        return expr;
2013
    }
2014
2015
    // 11.10 Binary Bitwise Operators
2016
2017
    function parseBitwiseANDExpression() {
2018
        var expr = parseEqualityExpression();
2019
2020
        while (match('&')) {
2021
            lex();
2022
            expr = {
2023
                type: Syntax.BinaryExpression,
2024
                operator: '&',
2025
                left: expr,
2026
                right: parseEqualityExpression()
2027
            };
2028
        }
2029
2030
        return expr;
2031
    }
2032
2033
    function parseBitwiseORExpression() {
2034
        var expr = parseBitwiseANDExpression();
2035
2036
        while (match('|')) {
2037
            lex();
2038
            expr = {
2039
                type: Syntax.BinaryExpression,
2040
                operator: '|',
2041
                left: expr,
2042
                right: parseBitwiseANDExpression()
2043
            };
2044
        }
2045
2046
        return expr;
2047
    }
2048
2049
    function parseBitwiseXORExpression() {
2050
        var expr = parseBitwiseORExpression();
2051
2052
        while (match('^')) {
2053
            lex();
2054
            expr = {
2055
                type: Syntax.BinaryExpression,
2056
                operator: '^',
2057
                left: expr,
2058
                right: parseBitwiseORExpression()
2059
            };
2060
        }
2061
2062
        return expr;
2063
    }
2064
2065
    // 11.11 Binary Logical Operators
2066
2067
    function parseLogicalANDExpression() {
2068
        var expr = parseBitwiseXORExpression();
2069
2070
        while (match('&&')) {
2071
            lex();
2072
            expr = {
2073
                type: Syntax.LogicalExpression,
2074
                operator: '&&',
2075
                left: expr,
2076
                right: parseBitwiseXORExpression()
2077
            };
2078
        }
2079
2080
        return expr;
2081
    }
2082
2083
    function parseLogicalORExpression() {
2084
        var expr = parseLogicalANDExpression();
2085
2086
        while (match('||')) {
2087
            lex();
2088
            expr = {
2089
                type: Syntax.LogicalExpression,
2090
                operator: '||',
2091
                left: expr,
2092
                right: parseLogicalANDExpression()
2093
            };
2094
        }
2095
2096
        return expr;
2097
    }
2098
2099
    // 11.12 Conditional Operator
2100
2101
    function parseConditionalExpression() {
2102
        var expr, previousAllowIn, consequent;
2103
2104
        expr = parseLogicalORExpression();
2105
2106
        if (match('?')) {
2107
            lex();
2108
            previousAllowIn = state.allowIn;
2109
            state.allowIn = true;
2110
            consequent = parseAssignmentExpression();
2111
            state.allowIn = previousAllowIn;
2112
            expect(':');
2113
2114
            expr = {
2115
                type: Syntax.ConditionalExpression,
2116
                test: expr,
2117
                consequent: consequent,
2118
                alternate: parseAssignmentExpression()
2119
            };
2120
        }
2121
2122
        return expr;
2123
    }
2124
2125
    // 11.13 Assignment Operators
2126
2127
    function parseAssignmentExpression() {
2128
        var expr;
2129
2130
        expr = parseConditionalExpression();
2131
2132
        if (matchAssign()) {
2133
            // LeftHandSideExpression
2134
            if (state.lastParenthesized !== expr && !isLeftHandSide(expr)) {
2135
                throwError({}, Messages.InvalidLHSInAssignment);
2136
            }
2137
2138
            // 11.13.1
2139
            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
2140
                throwError({}, Messages.StrictLHSAssignment);
2141
            }
2142
2143
            expr = {
2144
                type: Syntax.AssignmentExpression,
2145
                operator: lex().value,
2146
                left: expr,
2147
                right: parseAssignmentExpression()
2148
            };
2149
        }
2150
2151
        return expr;
2152
    }
2153
2154
    // 11.14 Comma Operator
2155
2156
    function parseExpression() {
2157
        var expr = parseAssignmentExpression();
2158
2159
        if (match(',')) {
2160
            expr = {
2161
                type: Syntax.SequenceExpression,
2162
                expressions: [ expr ]
2163
            };
2164
2165
            while (index < length) {
2166
                if (!match(',')) {
2167
                    break;
2168
                }
2169
                lex();
2170
                expr.expressions.push(parseAssignmentExpression());
2171
            }
2172
2173
        }
2174
        return expr;
2175
    }
2176
2177
    // 12.1 Block
2178
2179
    function parseStatementList() {
2180
        var list = [],
2181
            statement;
2182
2183
        while (index < length) {
2184
            if (match('}')) {
2185
                break;
2186
            }
2187
            statement = parseSourceElement();
2188
            if (typeof statement === 'undefined') {
2189
                break;
2190
            }
2191
            list.push(statement);
2192
        }
2193
2194
        return list;
2195
    }
2196
2197
    function parseBlock() {
2198
        var block;
2199
2200
        expect('{');
2201
2202
        block = parseStatementList();
2203
2204
        //expect('}');
2205
        expectCloseBracketWrapThrow();
2206
2207
        return {
2208
            type: Syntax.BlockStatement,
2209
            body: block
2210
        };
2211
    }
2212
2213
    // 12.2 Variable Statement
2214
2215
    function parseVariableIdentifier() {
2216
        var token = lex();
2217
2218
        if (token.type !== Token.Identifier) {
2219
            throwUnexpected(token);
2220
        }
2221
2222
        return {
2223
            type: Syntax.Identifier,
2224
            name: token.value
2225
        };
2226
    }
2227
2228
    function parseVariableDeclaration(kind) {
2229
        var id = parseVariableIdentifier(),
2230
            init = null;
2231
2232
        // 12.2.1
2233
        if (strict && isRestrictedWord(id.name)) {
2234
            throwErrorTolerant({}, Messages.StrictVarName);
2235
        }
2236
2237
        if (kind === 'const') {
2238
            expect('=');
2239
            init = parseAssignmentExpression();
2240
        } else if (match('=')) {
2241
            lex();
2242
            init = parseAssignmentExpression();
2243
        }
2244
2245
        return {
2246
            type: Syntax.VariableDeclarator,
2247
            id: id,
2248
            init: init
2249
        };
2250
    }
2251
2252
    function parseVariableDeclarationList(kind) {
2253
        var list = [];
2254
2255
        while (index < length) {
2256
            list.push(parseVariableDeclaration(kind));
2257
            if (!match(',')) {
2258
                break;
2259
            }
2260
            lex();
2261
        }
2262
2263
        return list;
2264
    }
2265
2266
    function parseVariableStatement() {
2267
        var declarations;
2268
2269
        expectKeyword('var');
2270
2271
        declarations = parseVariableDeclarationList();
2272
2273
        consumeSemicolon();
2274
2275
        return {
2276
            type: Syntax.VariableDeclaration,
2277
            declarations: declarations,
2278
            kind: 'var'
2279
        };
2280
    }
2281
2282
    // kind may be `const` or `let`
2283
    // Both are experimental and not in the specification yet.
2284
    // see http://wiki.ecmascript.org/doku.php?id=harmony:const
2285
    // and http://wiki.ecmascript.org/doku.php?id=harmony:let
2286
    function parseConstLetDeclaration(kind) {
2287
        var declarations;
2288
2289
        expectKeyword(kind);
2290
2291
        declarations = parseVariableDeclarationList(kind);
2292
2293
        consumeSemicolon();
2294
2295
        return {
2296
            type: Syntax.VariableDeclaration,
2297
            declarations: declarations,
2298
            kind: kind
2299
        };
2300
    }
2301
2302
    // 12.3 Empty Statement
2303
2304
    function parseEmptyStatement() {
2305
        expect(';');
2306
2307
        return {
2308
            type: Syntax.EmptyStatement
2309
        };
2310
    }
2311
2312
    // 12.4 Expression Statement
2313
2314
    function parseExpressionStatement() {
2315
        var expr = parseExpression();
2316
2317
        consumeSemicolon();
2318
2319
        return {
2320
            type: Syntax.ExpressionStatement,
2321
            expression: expr
2322
        };
2323
    }
2324
    
2325
	/**
2326
	 * for statements like if, while, for, etc.
2327
	 * Check for the ')' on the condition.  If
2328
	 * it is not present, catch the error, and backtrack
2329
	 * if we see a '{' instead (to continue parsing the block)
2330
	 */
2331
	function expectConditionCloseParenWrapThrow() {
2332
        // needs generalizing to a 'expect A but don't consume if you hit B or C'
2333
        try {
2334
            expect(')');
2335
        } catch (e) {
2336
            if (extra.errors) {
2337
	            pushError(e);
2338
	            // If a { was hit instead of a ) then don't consume it, let us assume a ')' was 
2339
	            // missed and the consequent block is OK
2340
	            if (source[e.index] === '{') {
2341
	              index=e.index;
2342
	              buffer=null;
2343
	            // activating this block will mean the following statement is parsed as a consequent / body.
2344
	            // without it the statement is considered not at all part of the enclosing statement at all
2345
	//            } else {
2346
	//              rewind();
2347
	            }
2348
            } else {
2349
                throw e;
2350
            }
2351
        }
2352
2353
	}
2354
    // 12.5 If statement
2355
2356
    function parseIfStatement() {
2357
        var test, consequent, alternate;
2358
2359
        expectKeyword('if');
2360
2361
        expect('(');
2362
2363
		test = parseExpression();
2364
2365
		expectConditionCloseParenWrapThrow();
2366
		
2367
        consequent = parseStatement();
2368
        // required because of the check in wrapTracking that returns nothing if node is undefined
2369
        if (!consequent) {
2370
            consequent = null;
2371
        }
2372
2373
        if (matchKeyword('else')) {
2374
            lex();
2375
            alternate = parseStatement();
2376
        } else {
2377
            alternate = null;
2378
        }
2379
2380
        return {
2381
            type: Syntax.IfStatement,
2382
            test: test,
2383
            consequent: consequent,
2384
            alternate: alternate
2385
        };
2386
    }
2387
2388
    // 12.6 Iteration Statements
2389
2390
    function parseDoWhileStatement() {
2391
        var body, test, oldInIteration;
2392
2393
        expectKeyword('do');
2394
2395
        oldInIteration = state.inIteration;
2396
        state.inIteration = true;
2397
2398
        body = parseStatement();
2399
2400
        state.inIteration = oldInIteration;
2401
2402
        expectKeyword('while');
2403
2404
        expect('(');
2405
2406
        test = parseExpression();
2407
2408
        expect(')');
2409
2410
        if (match(';')) {
2411
            lex();
2412
        }
2413
2414
        return {
2415
            type: Syntax.DoWhileStatement,
2416
            body: body,
2417
            test: test
2418
        };
2419
    }
2420
2421
    function parseWhileStatement() {
2422
        var test, body, oldInIteration;
2423
2424
        expectKeyword('while');
2425
2426
        expect('(');
2427
2428
        test = parseExpression();
2429
2430
		expectConditionCloseParenWrapThrow();
2431
		
2432
        oldInIteration = state.inIteration;
2433
        state.inIteration = true;
2434
2435
        body = parseStatement();
2436
2437
        state.inIteration = oldInIteration;
2438
2439
        return {
2440
            type: Syntax.WhileStatement,
2441
            test: test,
2442
            body: body
2443
        };
2444
    }
2445
2446
    function parseForVariableDeclaration() {
2447
        var token = lex();
2448
2449
        return {
2450
            type: Syntax.VariableDeclaration,
2451
            declarations: parseVariableDeclarationList(),
2452
            kind: token.value
2453
        };
2454
    }
2455
2456
    function parseForStatement() {
2457
        var init, test, update, left, right, body, oldInIteration;
2458
2459
        init = test = update = null;
2460
2461
        expectKeyword('for');
2462
2463
        expect('(');
2464
2465
        if (match(';')) {
2466
            lex();
2467
        } else {
2468
            if (matchKeyword('var') || matchKeyword('let')) {
2469
                state.allowIn = false;
2470
                init = parseForVariableDeclaration();
2471
                state.allowIn = true;
2472
2473
                if (init.declarations.length === 1 && matchKeyword('in')) {
2474
                    lex();
2475
                    left = init;
2476
                    right = parseExpression();
2477
                    init = null;
2478
                }
2479
            } else {
2480
                state.allowIn = false;
2481
                init = parseExpression();
2482
                state.allowIn = true;
2483
2484
                if (matchKeyword('in')) {
2485
                    // LeftHandSideExpression
2486
                    if (matchKeyword('in') && (state.lastParenthesized !== init && !isLeftHandSide(init))) {
2487
                        throwError({}, Messages.InvalidLHSInForIn);
2488
                    }
2489
                    lex();
2490
                    left = init;
2491
                    right = parseExpression();
2492
                    init = null;
2493
                }
2494
            }
2495
2496
            if (typeof left === 'undefined') {
2497
                expect(';');
2498
            }
2499
        }
2500
2501
        if (typeof left === 'undefined') {
2502
2503
            if (!match(';')) {
2504
                test = parseExpression();
2505
            }
2506
            expect(';');
2507
2508
            if (!match(')')) {
2509
                update = parseExpression();
2510
            }
2511
        }
2512
2513
//        expect(')');
2514
		expectConditionCloseParenWrapThrow();
2515
		
2516
        oldInIteration = state.inIteration;
2517
        state.inIteration = true;
2518
2519
        body = parseStatement();
2520
2521
        state.inIteration = oldInIteration;
2522
2523
        if (typeof left === 'undefined') {
2524
            return {
2525
                type: Syntax.ForStatement,
2526
                init: init,
2527
                test: test,
2528
                update: update,
2529
                body: body
2530
            };
2531
        }
2532
2533
        return {
2534
            type: Syntax.ForInStatement,
2535
            left: left,
2536
            right: right,
2537
            body: body,
2538
            each: false
2539
        };
2540
    }
2541
2542
    // 12.7 The continue statement
2543
2544
    function parseContinueStatement() {
2545
        var token, label = null;
2546
2547
        expectKeyword('continue');
2548
2549
        // Optimize the most common form: 'continue;'.
2550
        if (source[index] === ';') {
2551
            lex();
2552
2553
            if (!state.inIteration) {
2554
                throwError({}, Messages.IllegalContinue);
2555
            }
2556
2557
            return {
2558
                type: Syntax.ContinueStatement,
2559
                label: null
2560
            };
2561
        }
2562
2563
        if (peekLineTerminator()) {
2564
            if (!state.inIteration) {
2565
                throwError({}, Messages.IllegalContinue);
2566
            }
2567
2568
            return {
2569
                type: Syntax.ContinueStatement,
2570
                label: null
2571
            };
2572
        }
2573
2574
        token = lookahead();
2575
        if (token.type === Token.Identifier) {
2576
            label = parseVariableIdentifier();
2577
2578
            if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) {
2579
                throwError({}, Messages.UnknownLabel, label.name);
2580
            }
2581
        }
2582
2583
        consumeSemicolon();
2584
2585
        if (label === null && !state.inIteration) {
2586
            throwError({}, Messages.IllegalContinue);
2587
        }
2588
2589
        return {
2590
            type: Syntax.ContinueStatement,
2591
            label: label
2592
        };
2593
    }
2594
2595
    // 12.8 The break statement
2596
2597
    function parseBreakStatement() {
2598
        var token, label = null;
2599
2600
        expectKeyword('break');
2601
2602
        // Optimize the most common form: 'break;'.
2603
        if (source[index] === ';') {
2604
            lex();
2605
2606
            if (!(state.inIteration || state.inSwitch)) {
2607
                throwError({}, Messages.IllegalBreak);
2608
            }
2609
2610
            return {
2611
                type: Syntax.BreakStatement,
2612
                label: null
2613
            };
2614
        }
2615
2616
        if (peekLineTerminator()) {
2617
            if (!(state.inIteration || state.inSwitch)) {
2618
                throwError({}, Messages.IllegalBreak);
2619
            }
2620
2621
            return {
2622
                type: Syntax.BreakStatement,
2623
                label: null
2624
            };
2625
        }
2626
2627
        token = lookahead();
2628
        if (token.type === Token.Identifier) {
2629
            label = parseVariableIdentifier();
2630
2631
            if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) {
2632
                throwError({}, Messages.UnknownLabel, label.name);
2633
            }
2634
        }
2635
2636
        consumeSemicolon();
2637
2638
        if (label === null && !(state.inIteration || state.inSwitch)) {
2639
            throwError({}, Messages.IllegalBreak);
2640
        }
2641
2642
        return {
2643
            type: Syntax.BreakStatement,
2644
            label: label
2645
        };
2646
    }
2647
2648
    // 12.9 The return statement
2649
2650
    function parseReturnStatement() {
2651
        var token, argument = null;
2652
2653
        expectKeyword('return');
2654
2655
        if (!state.inFunctionBody) {
2656
            throwErrorTolerant({}, Messages.IllegalReturn);
2657
        }
2658
2659
        // 'return' followed by a space and an identifier is very common.
2660
        if (source[index] === ' ') {
2661
            if (isIdentifierStart(source[index + 1])) {
2662
                argument = parseExpression();
2663
                consumeSemicolon();
2664
                return {
2665
                    type: Syntax.ReturnStatement,
2666
                    argument: argument
2667
                };
2668
            }
2669
        }
2670
2671
        if (peekLineTerminator()) {
2672
            return {
2673
                type: Syntax.ReturnStatement,
2674
                argument: null
2675
            };
2676
        }
2677
2678
        if (!match(';')) {
2679
            token = lookahead();
2680
            if (!match('}') && token.type !== Token.EOF) {
2681
                argument = parseExpression();
2682
            }
2683
        }
2684
2685
        consumeSemicolon();
2686
2687
        return {
2688
            type: Syntax.ReturnStatement,
2689
            argument: argument
2690
        };
2691
    }
2692
2693
    // 12.10 The with statement
2694
2695
    function parseWithStatement() {
2696
        var object, body;
2697
2698
        if (strict) {
2699
            throwErrorTolerant({}, Messages.StrictModeWith);
2700
        }
2701
2702
        expectKeyword('with');
2703
2704
        expect('(');
2705
2706
        object = parseExpression();
2707
2708
        expect(')');
2709
2710
        body = parseStatement();
2711
2712
        return {
2713
            type: Syntax.WithStatement,
2714
            object: object,
2715
            body: body
2716
        };
2717
    }
2718
2719
    // 12.10 The swith statement
2720
2721
    function parseSwitchCase() {
2722
        var test,
2723
            consequent = [],
2724
            statement;
2725
2726
        if (matchKeyword('default')) {
2727
            lex();
2728
            test = null;
2729
        } else {
2730
            expectKeyword('case');
2731
            test = parseExpression();
2732
        }
2733
        expect(':');
2734
2735
        while (index < length) {
2736
            if (match('}') || matchKeyword('default') || matchKeyword('case')) {
2737
                break;
2738
            }
2739
            statement = parseStatement();
2740
            if (typeof statement === 'undefined') {
2741
                break;
2742
            }
2743
            consequent.push(statement);
2744
        }
2745
2746
        return {
2747
            type: Syntax.SwitchCase,
2748
            test: test,
2749
            consequent: consequent
2750
        };
2751
    }
2752
2753
    function parseSwitchStatement() {
2754
        var discriminant, cases, oldInSwitch;
2755
2756
        expectKeyword('switch');
2757
2758
        expect('(');
2759
2760
        discriminant = parseExpression();
2761
2762
        expect(')');
2763
2764
        expect('{');
2765
2766
        if (match('}')) {
2767
            lex();
2768
            return {
2769
                type: Syntax.SwitchStatement,
2770
                discriminant: discriminant
2771
            };
2772
        }
2773
2774
        cases = [];
2775
2776
        oldInSwitch = state.inSwitch;
2777
        state.inSwitch = true;
2778
2779
        while (index < length) {
2780
            if (match('}')) {
2781
                break;
2782
            }
2783
            cases.push(parseSwitchCase());
2784
        }
2785
2786
        state.inSwitch = oldInSwitch;
2787
2788
        expect('}');
2789
2790
        return {
2791
            type: Syntax.SwitchStatement,
2792
            discriminant: discriminant,
2793
            cases: cases
2794
        };
2795
    }
2796
2797
    // 12.13 The throw statement
2798
2799
    function parseThrowStatement() {
2800
        var argument;
2801
2802
        expectKeyword('throw');
2803
2804
        if (peekLineTerminator()) {
2805
            throwError({}, Messages.NewlineAfterThrow);
2806
        }
2807
2808
        argument = parseExpression();
2809
2810
        consumeSemicolon();
2811
2812
        return {
2813
            type: Syntax.ThrowStatement,
2814
            argument: argument
2815
        };
2816
    }
2817
2818
    // 12.14 The try statement
2819
2820
    function parseCatchClause() {
2821
        var param;
2822
2823
        expectKeyword('catch');
2824
2825
        expect('(');
2826
        if (!match(')')) {
2827
            param = parseExpression();
2828
            // 12.14.1
2829
            if (strict && param.type === Syntax.Identifier && isRestrictedWord(param.name)) {
2830
                throwErrorTolerant({}, Messages.StrictCatchVariable);
2831
            }
2832
        }
2833
        expect(')');
2834
2835
        return {
2836
            type: Syntax.CatchClause,
2837
            param: param,
2838
            guard: null,
2839
            body: parseBlock()
2840
        };
2841
    }
2842
2843
    function parseTryStatement() {
2844
        var block, handlers = [], finalizer = null;
2845
2846
        expectKeyword('try');
2847
2848
        block = parseBlock();
2849
2850
        if (matchKeyword('catch')) {
2851
            handlers.push(parseCatchClause());
2852
        }
2853
2854
        if (matchKeyword('finally')) {
2855
            lex();
2856
            finalizer = parseBlock();
2857
        }
2858
2859
        if (handlers.length === 0 && !finalizer) {
2860
            throwError({}, Messages.NoCatchOrFinally);
2861
        }
2862
2863
        return {
2864
            type: Syntax.TryStatement,
2865
            block: block,
2866
            handlers: handlers,
2867
            finalizer: finalizer
2868
        };
2869
    }
2870
2871
    // 12.15 The debugger statement
2872
2873
    function parseDebuggerStatement() {
2874
        expectKeyword('debugger');
2875
2876
        consumeSemicolon();
2877
2878
        return {
2879
            type: Syntax.DebuggerStatement
2880
        };
2881
    }
2882
2883
    // 12 Statements
2884
2885
    function parseStatement() {
2886
        var token = lookahead(),
2887
            expr,
2888
            labeledBody;
2889
2890
        if (token.type === Token.EOF) {
2891
            throwUnexpected(token);
2892
        }
2893
2894
        if (token.type === Token.Punctuator) {
2895
            switch (token.value) {
2896
            case ';':
2897
                return parseEmptyStatement();
2898
            case '{':
2899
                return parseBlock();
2900
            case '(':
2901
                return parseExpressionStatement();
2902
            default:
2903
                break;
2904
            }
2905
        }
2906
2907
        if (token.type === Token.Keyword) {
2908
            switch (token.value) {
2909
            case 'break':
2910
                return parseBreakStatement();
2911
            case 'continue':
2912
                return parseContinueStatement();
2913
            case 'debugger':
2914
                return parseDebuggerStatement();
2915
            case 'do':
2916
                return parseDoWhileStatement();
2917
            case 'for':
2918
                return parseForStatement();
2919
            case 'function':
2920
                return parseFunctionDeclaration();
2921
            case 'if':
2922
                return parseIfStatement();
2923
            case 'return':
2924
                return parseReturnStatement();
2925
            case 'switch':
2926
                return parseSwitchStatement();
2927
            case 'throw':
2928
                return parseThrowStatement();
2929
            case 'try':
2930
                return parseTryStatement();
2931
            case 'var':
2932
                return parseVariableStatement();
2933
            case 'while':
2934
                return parseWhileStatement();
2935
            case 'with':
2936
                return parseWithStatement();
2937
            default:
2938
                break;
2939
            }
2940
        }
2941
2942
        expr = parseExpression();
2943
2944
        // 12.12 Labelled Statements
2945
        if (expr && (expr.type === Syntax.Identifier) && match(':')) {
2946
            lex();
2947
2948
            if (Object.prototype.hasOwnProperty.call(state.labelSet, expr.name)) {
2949
                throwError({}, Messages.Redeclaration, 'Label', expr.name);
2950
            }
2951
2952
            state.labelSet[expr.name] = true;
2953
            labeledBody = parseStatement();
2954
            delete state.labelSet[expr.name];
2955
2956
            return {
2957
                type: Syntax.LabeledStatement,
2958
                label: expr,
2959
                body: labeledBody
2960
            };
2961
        }
2962
        
2963
        consumeSemicolon();
2964
2965
2966
        return {
2967
            type: Syntax.ExpressionStatement,
2968
            expression: expr
2969
        };
2970
    }
2971
2972
    // 13 Function Definition
2973
	function expectCloseBracketWrapThrow() {
2974
		if (extra.errors) {
2975
			// continue parsing even with missing close
2976
			// brace.  This gives a better AST for the
2977
			// block, as information about
2978
			// the parsed statements remain
2979
			try {
2980
				expect('}');
2981
			} catch (e) {
2982
				pushError(e);
2983
	        }
2984
		} else {
2985
			expect('}');
2986
		}
2987
	}
2988
2989
    function parseFunctionSourceElements() {
2990
        var sourceElement, sourceElements = [], token, directive, firstRestricted,
2991
            oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody;
2992
2993
        expect('{');
2994
2995
        while (index < length) {
2996
            token = lookahead();
2997
            if (token.type !== Token.StringLiteral) {
2998
                break;
2999
            }
3000
3001
            sourceElement = parseSourceElement();
3002
            sourceElements.push(sourceElement);
3003
            if (sourceElement.expression.type !== Syntax.Literal) {
3004
                // this is not directive
3005
                break;
3006
            }
3007
            directive = sliceSource(token.range[0] + 1, token.range[1] - 1);
3008
            if (directive === 'use strict') {
3009
                strict = true;
3010
                if (firstRestricted) {
3011
                    throwError(firstRestricted, Messages.StrictOctalLiteral);
3012
                }
3013
            } else {
3014
                if (!firstRestricted && token.octal) {
3015
                    firstRestricted = token;
3016
                }
3017
            }
3018
        }
3019
3020
        oldLabelSet = state.labelSet;
3021
        oldInIteration = state.inIteration;
3022
        oldInSwitch = state.inSwitch;
3023
        oldInFunctionBody = state.inFunctionBody;
3024
3025
        state.labelSet = {};
3026
        state.inIteration = false;
3027
        state.inSwitch = false;
3028
        state.inFunctionBody = true;
3029
3030
        while (index < length) {
3031
            if (match('}')) {
3032
                break;
3033
            }
3034
            sourceElement = parseSourceElement();
3035
            if (typeof sourceElement === 'undefined') {
3036
                break;
3037
            }
3038
            sourceElements.push(sourceElement);
3039
        }
3040
3041
		expectCloseBracketWrapThrow();
3042
3043
        state.labelSet = oldLabelSet;
3044
        state.inIteration = oldInIteration;
3045
        state.inSwitch = oldInSwitch;
3046
        state.inFunctionBody = oldInFunctionBody;
3047
3048
        return {
3049
            type: Syntax.BlockStatement,
3050
            body: sourceElements
3051
        };
3052
    }
3053
3054
    function parseFunctionDeclaration() {
3055
        var id, param, params = [], body, token, firstRestricted, message, previousStrict, paramSet;
3056
3057
        expectKeyword('function');
3058
        token = lookahead();
3059
        id = parseVariableIdentifier();
3060
        if (strict) {
3061
            if (isRestrictedWord(token.value)) {
3062
                throwError(token, Messages.StrictFunctionName);
3063
            }
3064
        } else {
3065
            if (isRestrictedWord(token.value)) {
3066
                firstRestricted = token;
3067
                message = Messages.StrictFunctionName;
3068
            } else if (isStrictModeReservedWord(token.value)) {
3069
                firstRestricted = token;
3070
                message = Messages.StrictReservedWord;
3071
            }
3072
        }
3073
3074
        expect('(');
3075
3076
        if (!match(')')) {
3077
            paramSet = {};
3078
            while (index < length) {
3079
                token = lookahead();
3080
                param = parseVariableIdentifier();
3081
                if (strict) {
3082
                    if (isRestrictedWord(token.value)) {
3083
                        throwError(token, Messages.StrictParamName);
3084
                    }
3085
                    if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
3086
                        throwError(token, Messages.StrictParamDupe);
3087
                    }
3088
                } else if (!firstRestricted) {
3089
                    if (isRestrictedWord(token.value)) {
3090
                        firstRestricted = token;
3091
                        message = Messages.StrictParamName;
3092
                    } else if (isStrictModeReservedWord(token.value)) {
3093
                        firstRestricted = token;
3094
                        message = Messages.StrictReservedWord;
3095
                    } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
3096
                        firstRestricted = token;
3097
                        message = Messages.StrictParamDupe;
3098
                    }
3099
                }
3100
                params.push(param);
3101
                paramSet[param.name] = true;
3102
                if (match(')')) {
3103
                    break;
3104
                }
3105
                expect(',');
3106
            }
3107
        }
3108
3109
        expect(')');
3110
3111
        previousStrict = strict;
3112
        body = parseFunctionSourceElements();
3113
        if (strict && firstRestricted) {
3114
            throwError(firstRestricted, message);
3115
        }
3116
        strict = previousStrict;
3117
3118
        return {
3119
            type: Syntax.FunctionDeclaration,
3120
            id: id,
3121
            params: params,
3122
            body: body
3123
        };
3124
    }
3125
3126
    function parseFunctionExpression() {
3127
        var token, id = null, firstRestricted, message, param, params = [], body, previousStrict, paramSet;
3128
3129
        expectKeyword('function');
3130
3131
        if (!match('(')) {
3132
            token = lookahead();
3133
            id = parseVariableIdentifier();
3134
            if (strict) {
3135
                if (isRestrictedWord(token.value)) {
3136
                    throwError(token, Messages.StrictFunctionName);
3137
                }
3138
            } else {
3139
                if (isRestrictedWord(token.value)) {
3140
                    firstRestricted = token;
3141
                    message = Messages.StrictFunctionName;
3142
                } else if (isStrictModeReservedWord(token.value)) {
3143
                    firstRestricted = token;
3144
                    message = Messages.StrictReservedWord;
3145
                }
3146
            }
3147
        }
3148
3149
        expect('(');
3150
3151
        if (!match(')')) {
3152
            paramSet = {};
3153
            while (index < length) {
3154
                token = lookahead();
3155
                param = parseVariableIdentifier();
3156
                if (strict) {
3157
                    if (isRestrictedWord(token.value)) {
3158
                        throwError(token, Messages.StrictParamName);
3159
                    }
3160
                    if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
3161
                        throwError(token, Messages.StrictParamDupe);
3162
                    }
3163
                } else if (!firstRestricted) {
3164
                    if (isRestrictedWord(token.value)) {
3165
                        firstRestricted = token;
3166
                        message = Messages.StrictParamName;
3167
                    } else if (isStrictModeReservedWord(token.value)) {
3168
                        firstRestricted = token;
3169
                        message = Messages.StrictReservedWord;
3170
                    } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
3171
                        firstRestricted = token;
3172
                        message = Messages.StrictParamDupe;
3173
                    }
3174
                }
3175
                params.push(param);
3176
                paramSet[param.name] = true;
3177
                if (match(')')) {
3178
                    break;
3179
                }
3180
                expect(',');
3181
            }
3182
        }
3183
3184
        expect(')');
3185
3186
        previousStrict = strict;
3187
        body = parseFunctionSourceElements();
3188
        if (strict && firstRestricted) {
3189
            throwError(firstRestricted, message);
3190
        }
3191
        strict = previousStrict;
3192
3193
        return {
3194
            type: Syntax.FunctionExpression,
3195
            id: id,
3196
            params: params,
3197
            body: body
3198
        };
3199
    }
3200
3201
    // 14 Program
3202
3203
    function parseSourceElement() {
3204
        var token = lookahead();
3205
3206
        if (token.type === Token.Keyword) {
3207
            switch (token.value) {
3208
            case 'const':
3209
            case 'let':
3210
                return parseConstLetDeclaration(token.value);
3211
            case 'function':
3212
                return parseFunctionDeclaration();
3213
            default:
3214
                return parseStatement();
3215
            }
3216
        }
3217
3218
        if (token.type !== Token.EOF) {
3219
            return parseStatement();
3220
        }
3221
    }
3222
3223
    function parseSourceElements() {
3224
        var sourceElement, sourceElements = [], token, directive, firstRestricted;
3225
3226
        while (index < length) {
3227
            token = lookahead();
3228
            if (token.type !== Token.StringLiteral) {
3229
                break;
3230
            }
3231
3232
            sourceElement = parseSourceElement();
3233
            sourceElements.push(sourceElement);
3234
            if (sourceElement.expression.type !== Syntax.Literal) {
3235
                // this is not directive
3236
                break;
3237
            }
3238
            directive = sliceSource(token.range[0] + 1, token.range[1] - 1);
3239
            if (directive === 'use strict') {
3240
                strict = true;
3241
                if (firstRestricted) {
3242
                    throwError(firstRestricted, Messages.StrictOctalLiteral);
3243
                }
3244
            } else {
3245
                if (!firstRestricted && token.octal) {
3246
                    firstRestricted = token;
3247
                }
3248
            }
3249
        }
3250
3251
        while (index < length) {
3252
            sourceElement = parseSourceElement();
3253
            if (typeof sourceElement === 'undefined') {
3254
                break;
3255
            }
3256
            sourceElements.push(sourceElement);
3257
        }
3258
        return sourceElements;
3259
    }
3260
3261
    function parseProgram() {
3262
        var program;
3263
        strict = false;
3264
        program = {
3265
            type: Syntax.Program,
3266
            body: parseSourceElements()
3267
        };
3268
        return program;
3269
    }
3270
3271
    // The following functions are needed only when the option to preserve
3272
    // the comments is active.
3273
3274
    function addComment(start, end, type, value) {
3275
        assert(typeof start === 'number', 'Comment must have valid position');
3276
3277
        // Because the way the actual token is scanned, often the comments
3278
        // (if any) are skipped twice during the lexical analysis.
3279
        // Thus, we need to skip adding a comment if the comment array already
3280
        // handled it.
3281
        if (extra.comments.length > 0) {
3282
            if (extra.comments[extra.comments.length - 1].range[1] > start) {
3283
                return;
3284
            }
3285
        }
3286
3287
        extra.comments.push({
3288
            range: [start, end],
3289
            type: type,
3290
            value: value
3291
        });
3292
    }
3293
3294
    function scanComment() {
3295
        var comment, ch, start, blockComment, lineComment;
3296
3297
        comment = '';
3298
        blockComment = false;
3299
        lineComment = false;
3300
3301
        while (index < length) {
3302
            ch = source[index];
3303
3304
            if (lineComment) {
3305
                ch = nextChar();
3306
                if (index >= length) {
3307
                    lineComment = false;
3308
                    comment += ch;
3309
                    addComment(start, index, 'Line', comment);
3310
                } else if (isLineTerminator(ch)) {
3311
                    lineComment = false;
3312
                    addComment(start, index, 'Line', comment);
3313
                    if (ch === '\r' && source[index] === '\n') {
3314
                        ++index;
3315
                    }
3316
                    ++lineNumber;
3317
                    lineStart = index;
3318
                    comment = '';
3319
                } else {
3320
                    comment += ch;
3321
                }
3322
            } else if (blockComment) {
3323
                if (isLineTerminator(ch)) {
3324
                    if (ch === '\r' && source[index + 1] === '\n') {
3325
                        ++index;
3326
                        comment += '\r\n';
3327
                    } else {
3328
                        comment += ch;
3329
                    }
3330
                    ++lineNumber;
3331
                    ++index;
3332
                    lineStart = index;
3333
                    if (index >= length) {
3334
                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3335
                    }
3336
                } else {
3337
                    ch = nextChar();
3338
                    if (index >= length) {
3339
                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3340
                    }
3341
                    comment += ch;
3342
                    if (ch === '*') {
3343
                        ch = source[index];
3344
                        if (ch === '/') {
3345
                            comment = comment.substr(0, comment.length - 1);
3346
                            blockComment = false;
3347
                            ++index;
3348
                            addComment(start, index, 'Block', comment);
3349
                            comment = '';
3350
                        }
3351
                    }
3352
                }
3353
            } else if (ch === '/') {
3354
                ch = source[index + 1];
3355
                if (ch === '/') {
3356
                    start = index;
3357
                    index += 2;
3358
                    lineComment = true;
3359
                } else if (ch === '*') {
3360
                    start = index;
3361
                    index += 2;
3362
                    blockComment = true;
3363
                    if (index >= length) {
3364
                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3365
                    }
3366
                } else {
3367
                    break;
3368
                }
3369
            } else if (isWhiteSpace(ch)) {
3370
                ++index;
3371
            } else if (isLineTerminator(ch)) {
3372
                ++index;
3373
                if (ch ===  '\r' && source[index] === '\n') {
3374
                    ++index;
3375
                }
3376
                ++lineNumber;
3377
                lineStart = index;
3378
            } else {
3379
                break;
3380
            }
3381
        }
3382
    }
3383
3384
    function collectToken() {
3385
        var token = extra.advance(),
3386
            range,
3387
            value;
3388
3389
        if (token.type !== Token.EOF) {
3390
            range = [token.range[0], token.range[1]];
3391
            value = sliceSource(token.range[0], token.range[1]);
3392
            extra.tokens.push({
3393
                type: TokenName[token.type],
3394
                value: value,
3395
                range: range
3396
            });
3397
        }
3398
3399
        return token;
3400
    }
3401
3402
    function collectRegex() {
3403
        var pos, regex, token;
3404
3405
        skipComment();
3406
3407
        pos = index;
3408
        regex = extra.scanRegExp();
3409
3410
        // Pop the previous token, which is likely '/' or '/='
3411
        if (extra.tokens.length > 0) {
3412
            token = extra.tokens[extra.tokens.length - 1];
3413
            if (token.range[0] === pos && token.type === 'Punctuator') {
3414
                if (token.value === '/' || token.value === '/=') {
3415
                    extra.tokens.pop();
3416
                }
3417
            }
3418
        }
3419
3420
        extra.tokens.push({
3421
            type: 'RegularExpression',
3422
            value: regex.literal,
3423
            range: [pos, index]
3424
        });
3425
3426
        return regex;
3427
    }
3428
3429
    function createLiteral(token) {
3430
        return {
3431
            type: Syntax.Literal,
3432
            value: token.value
3433
        };
3434
    }
3435
3436
    function createRawLiteral(token) {
3437
        return {
3438
            type: Syntax.Literal,
3439
            value: token.value,
3440
            raw: sliceSource(token.range[0], token.range[1])
3441
        };
3442
    }
3443
3444
    function wrapTrackingFunction(range, loc) {
3445
3446
        return function (parseFunction) {
3447
3448
            function isBinary(node) {
3449
                return node.type === Syntax.LogicalExpression ||
3450
                    node.type === Syntax.BinaryExpression;
3451
            }
3452
3453
            function visit(node) {
3454
                if (isBinary(node.left)) {
3455
                    visit(node.left);
3456
                }
3457
                if (isBinary(node.right)) {
3458
                    visit(node.right);
3459
                }
3460
3461
                if (range && typeof node.range === 'undefined') {
3462
                    node.range = [node.left.range[0], node.right.range[1]];
3463
                }
3464
                if (loc && typeof node.loc === 'undefined') {
3465
                    node.loc = {
3466
                        start: node.left.loc.start,
3467
                        end: node.right.loc.end
3468
                    };
3469
                }
3470
            }
3471
3472
            return function () {
3473
                var node, rangeInfo, locInfo;
3474
3475
                skipComment();
3476
                rangeInfo = [index, 0];
3477
                locInfo = {
3478
                    start: {
3479
                        line: lineNumber,
3480
                        column: index - lineStart
3481
                    }
3482
                };
3483
3484
                node = parseFunction.apply(null, arguments);
3485
                if (typeof node !== 'undefined') {
3486
3487
                    if (range) {
3488
                        rangeInfo[1] = index;
3489
                        node.range = rangeInfo;
3490
                    }
3491
3492
                    if (loc) {
3493
                        locInfo.end = {
3494
                            line: lineNumber,
3495
                            column: index - lineStart
3496
                        };
3497
                        node.loc = locInfo;
3498
                    }
3499
3500
                    if (isBinary(node)) {
3501
                        visit(node);
3502
                    }
3503
3504
                    if (node.type === Syntax.MemberExpression) {
3505
                        if (typeof node.object.range !== 'undefined') {
3506
                            node.range[0] = node.object.range[0];
3507
                        }
3508
                        if (typeof node.object.loc !== 'undefined') {
3509
                            node.loc.start = node.object.loc.start;
3510
                        }
3511
                    }
3512
                    return node;
3513
                }
3514
            };
3515
3516
        };
3517
    }
3518
3519
    function patch() {
3520
3521
        var wrapTracking;
3522
3523
        function wrapThrow(parseFunction) {
3524
            return function () {
3525
                try {
3526
                    return parseFunction.apply(null, arguments);
3527
                } catch (e) {
3528
					pushError(e);
3529
					return null;
3530
                }
3531
            };
3532
        }
3533
        
3534
        function wrapThrowParseStatement(parseFunction) {
3535
            return function () {
3536
                extra.statementStart = index; // record where attempting to parse statement from
3537
                try {
3538
                    return parseFunction.apply(null, arguments);
3539
                } catch (e) {
3540
					pushError(e);
3541
//					return null;
3542
                }
3543
            };
3544
        }
3545
3546
        if (extra.comments) {
3547
            extra.skipComment = skipComment;
3548
            skipComment = scanComment;
3549
        }
3550
3551
        if (extra.raw) {
3552
            extra.createLiteral = createLiteral;
3553
            createLiteral = createRawLiteral;
3554
        }
3555
3556
        if (extra.range || extra.loc || extra.errors) {
3557
3558
            wrapTracking = wrapTrackingFunction(extra.range, extra.loc);
3559
3560
            extra.parseAdditiveExpression = parseAdditiveExpression;
3561
            extra.parseAssignmentExpression = parseAssignmentExpression;
3562
            extra.parseBitwiseANDExpression = parseBitwiseANDExpression;
3563
            extra.parseBitwiseORExpression = parseBitwiseORExpression;
3564
            extra.parseBitwiseXORExpression = parseBitwiseXORExpression;
3565
            extra.parseBlock = parseBlock;
3566
            extra.parseFunctionSourceElements = parseFunctionSourceElements;
3567
            extra.parseCallMember = parseCallMember;
3568
            extra.parseCatchClause = parseCatchClause;
3569
            extra.parseComputedMember = parseComputedMember;
3570
            extra.parseConditionalExpression = parseConditionalExpression;
3571
            extra.parseConstLetDeclaration = parseConstLetDeclaration;
3572
            extra.parseEqualityExpression = parseEqualityExpression;
3573
            extra.parseExpression = parseExpression;
3574
            extra.parseForVariableDeclaration = parseForVariableDeclaration;
3575
            extra.parseFunctionDeclaration = parseFunctionDeclaration;
3576
            extra.parseFunctionExpression = parseFunctionExpression;
3577
            extra.parseLogicalANDExpression = parseLogicalANDExpression;
3578
            extra.parseLogicalORExpression = parseLogicalORExpression;
3579
            extra.parseMultiplicativeExpression = parseMultiplicativeExpression;
3580
            extra.parseNewExpression = parseNewExpression;
3581
            extra.parseNonComputedMember = parseNonComputedMember;
3582
            extra.parseNonComputedProperty = parseNonComputedProperty;
3583
            extra.parseObjectProperty = parseObjectProperty;
3584
            extra.parseObjectPropertyKey = parseObjectPropertyKey;
3585
            extra.parsePostfixExpression = parsePostfixExpression;
3586
            extra.parsePrimaryExpression = parsePrimaryExpression;
3587
            extra.parseProgram = parseProgram;
3588
            extra.parsePropertyFunction = parsePropertyFunction;
3589
            extra.parseRelationalExpression = parseRelationalExpression;
3590
            extra.parseStatement = parseStatement;
3591
            extra.parseShiftExpression = parseShiftExpression;
3592
            extra.parseSwitchCase = parseSwitchCase;
3593
            extra.parseUnaryExpression = parseUnaryExpression;
3594
            extra.parseVariableDeclaration = parseVariableDeclaration;
3595
            extra.parseVariableIdentifier = parseVariableIdentifier;
3596
            extra.consumeSemicolon = consumeSemicolon;
3597
3598
            parseAdditiveExpression = wrapTracking(extra.parseAdditiveExpression);
3599
            parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression);
3600
            parseBitwiseANDExpression = wrapTracking(extra.parseBitwiseANDExpression);
3601
            parseBitwiseORExpression = wrapTracking(extra.parseBitwiseORExpression);
3602
            parseBitwiseXORExpression = wrapTracking(extra.parseBitwiseXORExpression);
3603
            parseBlock = wrapTracking(extra.parseBlock);
3604
            parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements);
3605
            parseCallMember = wrapTracking(extra.parseCallMember);
3606
            parseCatchClause = wrapTracking(extra.parseCatchClause);
3607
            parseComputedMember = wrapTracking(extra.parseComputedMember);
3608
            parseConditionalExpression = wrapTracking(extra.parseConditionalExpression);
3609
            parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration);
3610
            parseEqualityExpression = wrapTracking(extra.parseEqualityExpression);
3611
            parseExpression = wrapTracking(extra.parseExpression);
3612
            parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration);
3613
            parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration);
3614
            parseFunctionExpression = wrapTracking(extra.parseFunctionExpression);
3615
            parseLogicalANDExpression = wrapTracking(extra.parseLogicalANDExpression);
3616
            parseLogicalORExpression = wrapTracking(extra.parseLogicalORExpression);
3617
            parseMultiplicativeExpression = wrapTracking(extra.parseMultiplicativeExpression);
3618
            parseNewExpression = wrapTracking(extra.parseNewExpression);
3619
            parseNonComputedMember = wrapTracking(extra.parseNonComputedMember);
3620
            parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty);
3621
            parseObjectProperty = wrapTracking(extra.parseObjectProperty);
3622
            parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey);
3623
            parsePostfixExpression = wrapTracking(extra.parsePostfixExpression);
3624
            parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression);
3625
            parseProgram = wrapTracking(extra.parseProgram);
3626
            parsePropertyFunction = wrapTracking(extra.parsePropertyFunction);
3627
            parseRelationalExpression = wrapTracking(extra.parseRelationalExpression);
3628
            parseStatement = wrapTracking(extra.parseStatement);
3629
            parseShiftExpression = wrapTracking(extra.parseShiftExpression);
3630
            parseSwitchCase = wrapTracking(extra.parseSwitchCase);
3631
            parseUnaryExpression = wrapTracking(extra.parseUnaryExpression);
3632
            parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration);
3633
            parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier);
3634
        }
3635
        
3636
        if (extra.errors) {
3637
            parseStatement = wrapThrowParseStatement(parseStatement);
3638
            parseExpression = wrapThrow(parseExpression);
3639
            // this enables 'foo.<EOF>' to return something
3640
            parseNonComputedProperty = wrapThrow(parseNonComputedProperty);
3641
            consumeSemicolon = wrapThrow(consumeSemicolon);
3642
        }
3643
3644
        if (typeof extra.tokens !== 'undefined') {
3645
            extra.advance = advance;
3646
            extra.scanRegExp = scanRegExp;
3647
3648
            advance = collectToken;
3649
            scanRegExp = collectRegex;
3650
        }
3651
    }
3652
3653
    function unpatch() {
3654
        if (typeof extra.skipComment === 'function') {
3655
            skipComment = extra.skipComment;
3656
        }
3657
3658
        if (extra.raw) {
3659
            createLiteral = extra.createLiteral;
3660
        }
3661
3662
        if (extra.range || extra.loc || extra.errors) {
3663
            parseAdditiveExpression = extra.parseAdditiveExpression;
3664
            parseAssignmentExpression = extra.parseAssignmentExpression;
3665
            parseBitwiseANDExpression = extra.parseBitwiseANDExpression;
3666
            parseBitwiseORExpression = extra.parseBitwiseORExpression;
3667
            parseBitwiseXORExpression = extra.parseBitwiseXORExpression;
3668
            parseBlock = extra.parseBlock;
3669
            parseFunctionSourceElements = extra.parseFunctionSourceElements;
3670
            parseCallMember = extra.parseCallMember;
3671
            parseCatchClause = extra.parseCatchClause;
3672
            parseComputedMember = extra.parseComputedMember;
3673
            parseConditionalExpression = extra.parseConditionalExpression;
3674
            parseConstLetDeclaration = extra.parseConstLetDeclaration;
3675
            parseEqualityExpression = extra.parseEqualityExpression;
3676
            parseExpression = extra.parseExpression;
3677
            parseForVariableDeclaration = extra.parseForVariableDeclaration;
3678
            parseFunctionDeclaration = extra.parseFunctionDeclaration;
3679
            parseFunctionExpression = extra.parseFunctionExpression;
3680
            parseLogicalANDExpression = extra.parseLogicalANDExpression;
3681
            parseLogicalORExpression = extra.parseLogicalORExpression;
3682
            parseMultiplicativeExpression = extra.parseMultiplicativeExpression;
3683
            parseNewExpression = extra.parseNewExpression;
3684
            parseNonComputedMember = extra.parseNonComputedMember;
3685
            parseNonComputedProperty = extra.parseNonComputedProperty;
3686
            parseObjectProperty = extra.parseObjectProperty;
3687
            parseObjectPropertyKey = extra.parseObjectPropertyKey;
3688
            parsePrimaryExpression = extra.parsePrimaryExpression;
3689
            parsePostfixExpression = extra.parsePostfixExpression;
3690
            parseProgram = extra.parseProgram;
3691
            parsePropertyFunction = extra.parsePropertyFunction;
3692
            parseRelationalExpression = extra.parseRelationalExpression;
3693
            parseStatement = extra.parseStatement;
3694
            parseShiftExpression = extra.parseShiftExpression;
3695
            parseSwitchCase = extra.parseSwitchCase;
3696
            parseUnaryExpression = extra.parseUnaryExpression;
3697
            parseVariableDeclaration = extra.parseVariableDeclaration;
3698
            parseVariableIdentifier = extra.parseVariableIdentifier;
3699
            consumeSemicolon = extra.consumeSemicolon;
3700
        }
3701
3702
        if (typeof extra.scanRegExp === 'function') {
3703
            advance = extra.advance;
3704
            scanRegExp = extra.scanRegExp;
3705
        }
3706
    }
3707
3708
    function stringToArray(str) {
3709
        var length = str.length,
3710
            result = [],
3711
            i;
3712
        for (i = 0; i < length; ++i) {
3713
            result[i] = str.charAt(i);
3714
        }
3715
        return result;
3716
    }
3717
3718
    function parse(code, options) {
3719
        var program, toString;
3720
3721
        toString = String;
3722
        if (typeof code !== 'string' && !(code instanceof String)) {
3723
            code = toString(code);
3724
        }
3725
3726
        source = code;
3727
        index = 0;
3728
        lineNumber = (source.length > 0) ? 1 : 0;
3729
        lineStart = 0;
3730
        length = source.length;
3731
        buffer = null;
3732
        state = {
3733
            allowIn: true,
3734
            labelSet: {},
3735
            lastParenthesized: null,
3736
            inFunctionBody: false,
3737
            inIteration: false,
3738
            inSwitch: false
3739
        };
3740
3741
        extra = {};
3742
        if (typeof options !== 'undefined') {
3743
            extra.range = (typeof options.range === 'boolean') && options.range;
3744
            extra.loc = (typeof options.loc === 'boolean') && options.loc;
3745
            extra.raw = (typeof options.raw === 'boolean') && options.raw;
3746
            if (typeof options.tokens === 'boolean' && options.tokens) {
3747
                extra.tokens = [];
3748
            }
3749
            if (typeof options.comment === 'boolean' && options.comment) {
3750
                extra.comments = [];
3751
            }
3752
            if (typeof options.tolerant === 'boolean' && options.tolerant) {
3753
                extra.errors = [];
3754
            }
3755
        }
3756
3757
        if (length > 0) {
3758
            if (typeof source[0] === 'undefined') {
3759
                // Try first to convert to a string. This is good as fast path
3760
                // for old IE which understands string indexing for string
3761
                // literals only and not for string object.
3762
                if (code instanceof String) {
3763
                    source = code.valueOf();
3764
                }
3765
3766
                // Force accessing the characters via an array.
3767
                if (typeof source[0] === 'undefined') {
3768
                    source = stringToArray(code);
3769
                }
3770
            }
3771
        }
3772
3773
        patch();
3774
        try {
3775
            program = parseProgram();
3776
            if (typeof extra.comments !== 'undefined') {
3777
                program.comments = extra.comments;
3778
            }
3779
            if (typeof extra.tokens !== 'undefined') {
3780
                program.tokens = extra.tokens;
3781
            }
3782
            if (typeof extra.errors !== 'undefined') {
3783
                program.errors = extra.errors;
3784
            }
3785
        } catch (e) {
3786
            throw e;
3787
        } finally {
3788
            unpatch();
3789
            extra = {};
3790
        }
3791
3792
        return program;
3793
    }
3794
3795
    // Sync with package.json.
3796
    exports.version = '1.0.0-dev';
3797
4174
3798
    exports.parse = parse;
4175
    exports.parse = parse;
3799
4176
Lines 3818-3822 Link Here
3818
        return types;
4195
        return types;
3819
    }());
4196
    }());
3820
4197
3821
}(typeof exports === 'undefined' ? (esprima = {}) : exports));
4198
}));
3822
/* vim: set sw=4 ts=4 et tw=80 : */
4199
/* vim: set sw=4 ts=4 et tw=80 : */
(-)a/bundles/org.eclipse.orion.client.javascript/web/esprima/esprima_tolerant.js (-4156 lines)
Lines 1-4156 Link Here
1
/*
2
  Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
3
  Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
4
  Copyright (C) 2013 Mathias Bynens <mathias@qiwi.be>
5
  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
6
  Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
7
  Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
8
  Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
9
  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
10
  Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
11
  Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
12
13
  Redistribution and use in source and binary forms, with or without
14
  modification, are permitted provided that the following conditions are met:
15
16
    * Redistributions of source code must retain the above copyright
17
      notice, this list of conditions and the following disclaimer.
18
    * Redistributions in binary form must reproduce the above copyright
19
      notice, this list of conditions and the following disclaimer in the
20
      documentation and/or other materials provided with the distribution.
21
22
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
26
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
*/
33
34
/*jslint bitwise:true plusplus:true */
35
/*global esprima:true, define:true, exports:true, window: true,
36
createLocationMarker: true,
37
throwError: true, generateStatement: true, peek: true,
38
parseAssignmentExpression: true, parseBlock: true, 
39
expectConditionCloseBracketWrapThrow: true, parseExpression: true,
40
parseFunctionDeclaration: true, parseFunctionExpression: true,
41
parseFunctionSourceElements: true, parseVariableIdentifier: true,
42
parseLeftHandSideExpression: true,
43
parseUnaryExpression: true,
44
parseStatement: true, parseSourceElement: true */
45
46
(function (root, factory) {
47
    'use strict';
48
49
    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
50
    // Rhino, and plain browser loading.
51
    if (typeof define === 'function' && define.amd) {
52
        define(['exports'], factory);
53
    } else if (typeof exports !== 'undefined') {
54
        factory(exports);
55
    } else {
56
        factory((root.esprima = {}));
57
    }
58
}(this, function (exports) {
59
    'use strict';
60
61
    var Token,
62
        TokenName,
63
        FnExprTokens,
64
        Syntax,
65
        PropertyKind,
66
        Messages,
67
        Regex,
68
        SyntaxTreeDelegate,
69
        source,
70
        strict,
71
        index,
72
        lineNumber,
73
        lineStart,
74
        length,
75
        delegate,
76
        lookahead,
77
        state,
78
        extra;
79
80
    Token = {
81
        BooleanLiteral: 1,
82
        EOF: 2,
83
        Identifier: 3,
84
        Keyword: 4,
85
        NullLiteral: 5,
86
        NumericLiteral: 6,
87
        Punctuator: 7,
88
        StringLiteral: 8,
89
        RegularExpression: 9
90
    };
91
92
    TokenName = {};
93
    TokenName[Token.BooleanLiteral] = 'Boolean';
94
    TokenName[Token.EOF] = '<end>';
95
    TokenName[Token.Identifier] = 'Identifier';
96
    TokenName[Token.Keyword] = 'Keyword';
97
    TokenName[Token.NullLiteral] = 'Null';
98
    TokenName[Token.NumericLiteral] = 'Numeric';
99
    TokenName[Token.Punctuator] = 'Punctuator';
100
    TokenName[Token.StringLiteral] = 'String';
101
    TokenName[Token.RegularExpression] = 'RegularExpression';
102
103
    // A function following one of those tokens is an expression.
104
    FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
105
                    'return', 'case', 'delete', 'throw', 'void',
106
                    // assignment operators
107
                    '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
108
                    '&=', '|=', '^=', ',',
109
                    // binary/unary operators
110
                    '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
111
                    '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
112
                    '<=', '<', '>', '!=', '!=='];
113
114
    Syntax = {
115
        AssignmentExpression: 'AssignmentExpression',
116
        ArrayExpression: 'ArrayExpression',
117
        BlockStatement: 'BlockStatement',
118
        BinaryExpression: 'BinaryExpression',
119
        BreakStatement: 'BreakStatement',
120
        CallExpression: 'CallExpression',
121
        CatchClause: 'CatchClause',
122
        ConditionalExpression: 'ConditionalExpression',
123
        ContinueStatement: 'ContinueStatement',
124
        DoWhileStatement: 'DoWhileStatement',
125
        DebuggerStatement: 'DebuggerStatement',
126
        EmptyStatement: 'EmptyStatement',
127
        ExpressionStatement: 'ExpressionStatement',
128
        ForStatement: 'ForStatement',
129
        ForInStatement: 'ForInStatement',
130
        FunctionDeclaration: 'FunctionDeclaration',
131
        FunctionExpression: 'FunctionExpression',
132
        Identifier: 'Identifier',
133
        IfStatement: 'IfStatement',
134
        Literal: 'Literal',
135
        LabeledStatement: 'LabeledStatement',
136
        LogicalExpression: 'LogicalExpression',
137
        MemberExpression: 'MemberExpression',
138
        NewExpression: 'NewExpression',
139
        ObjectExpression: 'ObjectExpression',
140
        Program: 'Program',
141
        Property: 'Property',
142
        ReturnStatement: 'ReturnStatement',
143
        SequenceExpression: 'SequenceExpression',
144
        SwitchStatement: 'SwitchStatement',
145
        SwitchCase: 'SwitchCase',
146
        ThisExpression: 'ThisExpression',
147
        ThrowStatement: 'ThrowStatement',
148
        TryStatement: 'TryStatement',
149
        UnaryExpression: 'UnaryExpression',
150
        UpdateExpression: 'UpdateExpression',
151
        VariableDeclaration: 'VariableDeclaration',
152
        VariableDeclarator: 'VariableDeclarator',
153
        WhileStatement: 'WhileStatement',
154
        WithStatement: 'WithStatement'
155
    };
156
157
    PropertyKind = {
158
        Data: 1,
159
        Get: 2,
160
        Set: 4
161
    };
162
163
    // Error messages should be identical to V8.
164
    Messages = {
165
        UnexpectedToken:  'Unexpected token %0',
166
        UnexpectedNumber:  'Unexpected number',
167
        UnexpectedString:  'Unexpected string',
168
        UnexpectedIdentifier:  'Unexpected identifier',
169
        UnexpectedReserved:  'Unexpected reserved word',
170
        UnexpectedEOS:  'Unexpected end of input',
171
        NewlineAfterThrow:  'Illegal newline after throw',
172
        InvalidRegExp: 'Invalid regular expression',
173
        UnterminatedRegExp:  'Invalid regular expression: missing /',
174
        InvalidLHSInAssignment:  'Invalid left-hand side in assignment',
175
        InvalidLHSInForIn:  'Invalid left-hand side in for-in',
176
        MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
177
        NoCatchOrFinally:  'Missing catch or finally after try',
178
        UnknownLabel: 'Undefined label \'%0\'',
179
        Redeclaration: '%0 \'%1\' has already been declared',
180
        IllegalContinue: 'Illegal continue statement',
181
        IllegalBreak: 'Illegal break statement',
182
        IllegalReturn: 'Illegal return statement',
183
        StrictModeWith:  'Strict mode code may not include a with statement',
184
        StrictCatchVariable:  'Catch variable may not be eval or arguments in strict mode',
185
        StrictVarName:  'Variable name may not be eval or arguments in strict mode',
186
        StrictParamName:  'Parameter name eval or arguments is not allowed in strict mode',
187
        StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
188
        StrictFunctionName:  'Function name may not be eval or arguments in strict mode',
189
        StrictOctalLiteral:  'Octal literals are not allowed in strict mode.',
190
        StrictDelete:  'Delete of an unqualified identifier in strict mode.',
191
        StrictDuplicateProperty:  'Duplicate data property in object literal not allowed in strict mode',
192
        AccessorDataProperty:  'Object literal may not have data and accessor property with the same name',
193
        AccessorGetSet:  'Object literal may not have multiple get/set accessors with the same name',
194
        StrictLHSAssignment:  'Assignment to eval or arguments is not allowed in strict mode',
195
        StrictLHSPostfix:  'Postfix increment/decrement may not have eval or arguments operand in strict mode',
196
        StrictLHSPrefix:  'Prefix increment/decrement may not have eval or arguments operand in strict mode',
197
        StrictReservedWord:  'Use of future reserved word in strict mode'
198
    };
199
200
    // See also tools/generate-unicode-regex.py.
201
    Regex = {
202
        NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\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\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\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-\u0C33\u0C35-\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-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\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\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\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-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\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]'),
203
        NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\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\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\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\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\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\u0D02\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\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\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\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-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\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\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\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-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\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-\uFE26\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]')
204
    };
205
206
    // Ensure the condition is true, otherwise throw an error.
207
    // This is only to have a better contract semantic, i.e. another safety net
208
    // to catch a logic error. The condition shall be fulfilled in normal case.
209
    // Do NOT use this to enforce a certain condition on any user input.
210
211
    function assert(condition, message) {
212
        if (!condition) {
213
            throw new Error('ASSERT: ' + message);
214
        }
215
    }
216
217
    function isDecimalDigit(ch) {
218
        return (ch >= 48 && ch <= 57);   // 0..9
219
    }
220
221
    function isHexDigit(ch) {
222
        return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
223
    }
224
225
    function isOctalDigit(ch) {
226
        return '01234567'.indexOf(ch) >= 0;
227
    }
228
229
230
    // 7.2 White Space
231
232
    function isWhiteSpace(ch) {
233
        return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
234
            (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
235
    }
236
237
    // 7.3 Line Terminators
238
239
    function isLineTerminator(ch) {
240
        return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
241
    }
242
243
    // 7.6 Identifier Names and Identifiers
244
245
    function isIdentifierStart(ch) {
246
        return (ch === 36) || (ch === 95) ||  // $ (dollar) and _ (underscore)
247
            (ch >= 65 && ch <= 90) ||         // A..Z
248
            (ch >= 97 && ch <= 122) ||        // a..z
249
            (ch === 92) ||                    // \ (backslash)
250
            ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
251
    }
252
253
    function isIdentifierPart(ch) {
254
        return (ch === 36) || (ch === 95) ||  // $ (dollar) and _ (underscore)
255
            (ch >= 65 && ch <= 90) ||         // A..Z
256
            (ch >= 97 && ch <= 122) ||        // a..z
257
            (ch >= 48 && ch <= 57) ||         // 0..9
258
            (ch === 92) ||                    // \ (backslash)
259
            ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
260
    }
261
262
    // 7.6.1.2 Future Reserved Words
263
264
    function isFutureReservedWord(id) {
265
        switch (id) {
266
        case 'class':
267
        case 'enum':
268
        case 'export':
269
        case 'extends':
270
        case 'import':
271
        case 'super':
272
            return true;
273
        default:
274
            return false;
275
        }
276
    }
277
278
    function isStrictModeReservedWord(id) {
279
        switch (id) {
280
        case 'implements':
281
        case 'interface':
282
        case 'package':
283
        case 'private':
284
        case 'protected':
285
        case 'public':
286
        case 'static':
287
        case 'yield':
288
        case 'let':
289
            return true;
290
        default:
291
            return false;
292
        }
293
    }
294
295
    function isRestrictedWord(id) {
296
        return id === 'eval' || id === 'arguments';
297
    }
298
299
    // 7.6.1.1 Keywords
300
301
    function isKeyword(id) {
302
        if (strict && isStrictModeReservedWord(id)) {
303
            return true;
304
        }
305
306
        // 'const' is specialized as Keyword in V8.
307
        // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.
308
        // Some others are from future reserved words.
309
310
        switch (id.length) {
311
        case 2:
312
            return (id === 'if') || (id === 'in') || (id === 'do');
313
        case 3:
314
            return (id === 'var') || (id === 'for') || (id === 'new') ||
315
                (id === 'try') || (id === 'let');
316
        case 4:
317
            return (id === 'this') || (id === 'else') || (id === 'case') ||
318
                (id === 'void') || (id === 'with') || (id === 'enum');
319
        case 5:
320
            return (id === 'while') || (id === 'break') || (id === 'catch') ||
321
                (id === 'throw') || (id === 'const') || (id === 'yield') ||
322
                (id === 'class') || (id === 'super');
323
        case 6:
324
            return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
325
                (id === 'switch') || (id === 'export') || (id === 'import');
326
        case 7:
327
            return (id === 'default') || (id === 'finally') || (id === 'extends');
328
        case 8:
329
            return (id === 'function') || (id === 'continue') || (id === 'debugger');
330
        case 10:
331
            return (id === 'instanceof');
332
        default:
333
            return false;
334
        }
335
    }
336
337
    // 7.4 Comments
338
339
    function addComment(type, value, start, end, loc) {
340
        var comment, attacher;
341
342
        assert(typeof start === 'number', 'Comment must have valid position');
343
344
        // Because the way the actual token is scanned, often the comments
345
        // (if any) are skipped twice during the lexical analysis.
346
        // Thus, we need to skip adding a comment if the comment array already
347
        // handled it.
348
        if (state.lastCommentStart >= start) {
349
            return;
350
        }
351
        state.lastCommentStart = start;
352
353
        comment = {
354
            type: type,
355
            value: value
356
        };
357
        if (extra.range) {
358
            comment.range = [start, end];
359
        }
360
        if (extra.loc) {
361
            comment.loc = loc;
362
        }
363
        extra.comments.push(comment);
364
365
        if (extra.attachComment) {
366
            attacher = {
367
                comment: comment,
368
                leading: null,
369
                trailing: null,
370
                range: [start, end]
371
            };
372
            extra.pendingComments.push(attacher);
373
        }
374
    }
375
376
    function skipSingleLineComment() {
377
        var start, loc, ch, comment;
378
379
        start = index - 2;
380
        loc = {
381
            start: {
382
                line: lineNumber,
383
                column: index - lineStart - 2
384
            }
385
        };
386
387
        while (index < length) {
388
            ch = source.charCodeAt(index);
389
            ++index;
390
            if (isLineTerminator(ch)) {
391
                if (extra.comments) {
392
                    comment = source.slice(start + 2, index - 1);
393
                    loc.end = {
394
                        line: lineNumber,
395
                        column: index - lineStart - 1
396
                    };
397
                    addComment('Line', comment, start, index - 1, loc);
398
                }
399
                if (ch === 13 && source.charCodeAt(index) === 10) {
400
                    ++index;
401
                }
402
                ++lineNumber;
403
                lineStart = index;
404
                return;
405
            }
406
        }
407
408
        if (extra.comments) {
409
            comment = source.slice(start + 2, index);
410
            loc.end = {
411
                line: lineNumber,
412
                column: index - lineStart
413
            };
414
            addComment('Line', comment, start, index, loc);
415
        }
416
    }
417
418
    function skipMultiLineComment() {
419
        var start, loc, ch, comment;
420
421
        if (extra.comments) {
422
            start = index - 2;
423
            loc = {
424
                start: {
425
                    line: lineNumber,
426
                    column: index - lineStart - 2
427
                }
428
            };
429
        }
430
431
        while (index < length) {
432
            ch = source.charCodeAt(index);
433
            if (isLineTerminator(ch)) {
434
                if (ch === 13 && source.charCodeAt(index + 1) === 10) {
435
                    ++index;
436
                }
437
                ++lineNumber;
438
                ++index;
439
                lineStart = index;
440
                if (index >= length) {
441
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
442
                }
443
            } else if (ch === 42) {
444
                // Block comment ends with '*/' (char #42, char #47).
445
                if (source.charCodeAt(index + 1) === 47) {
446
                    ++index;
447
                    ++index;
448
                    if (extra.comments) {
449
                        comment = source.slice(start + 2, index - 2);
450
                        loc.end = {
451
                            line: lineNumber,
452
                            column: index - lineStart
453
                        };
454
                        addComment('Block', comment, start, index, loc);
455
                    }
456
                    return;
457
                }
458
                ++index;
459
            } else {
460
                ++index;
461
            }
462
        }
463
464
        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
465
    }
466
467
    function skipComment() {
468
        var ch, start;
469
470
        start = (index === 0);
471
        while (index < length) {
472
            ch = source.charCodeAt(index);
473
474
            if (isWhiteSpace(ch)) {
475
                ++index;
476
            } else if (isLineTerminator(ch)) {
477
                ++index;
478
                if (ch === 13 && source.charCodeAt(index) === 10) {
479
                    ++index;
480
                }
481
                ++lineNumber;
482
                lineStart = index;
483
                start = true;
484
            } else if (ch === 47) { // 47 is '/'
485
                ch = source.charCodeAt(index + 1);
486
                if (ch === 47) {
487
                    ++index;
488
                    ++index;
489
                    skipSingleLineComment();
490
                    start = true;
491
                } else if (ch === 42) {  // 42 is '*'
492
                    ++index;
493
                    ++index;
494
                    skipMultiLineComment();
495
                } else {
496
                    break;
497
                }
498
            } else if (start && ch === 45) { // 45 is '-'
499
                // 62 is '>'
500
                if ((source.charCodeAt(index + 1) === 45) && (source.charCodeAt(index + 2) === 62)) {
501
                    // '-->' is a single-line comment
502
                    index += 3;
503
                    skipSingleLineComment();
504
                } else {
505
                    break;
506
                }
507
            } else if (ch === 60) { // 60 is '<'
508
                if (source.slice(index + 1, index + 4) === '!--') {
509
                    ++index; // `<`
510
                    ++index; // `!`
511
                    ++index; // `-`
512
                    ++index; // `-`
513
                    skipSingleLineComment();
514
                } else {
515
                    break;
516
                }
517
            } else {
518
                break;
519
            }
520
        }
521
    }
522
523
    function scanHexEscape(prefix) {
524
        var i, len, ch, code = 0;
525
526
        len = (prefix === 'u') ? 4 : 2;
527
        for (i = 0; i < len; ++i) {
528
            if (index < length && isHexDigit(source[index])) {
529
                ch = source[index++];
530
                code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
531
            } else {
532
                return '';
533
            }
534
        }
535
        return String.fromCharCode(code);
536
    }
537
538
    function getEscapedIdentifier() {
539
        var ch, id;
540
541
        ch = source.charCodeAt(index++);
542
        id = String.fromCharCode(ch);
543
544
        // '\u' (char #92, char #117) denotes an escaped character.
545
        if (ch === 92) {
546
            if (source.charCodeAt(index) !== 117) {
547
                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
548
            }
549
            ++index;
550
            ch = scanHexEscape('u');
551
            if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
552
                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
553
            }
554
            id = ch;
555
        }
556
557
        while (index < length) {
558
            ch = source.charCodeAt(index);
559
            if (!isIdentifierPart(ch)) {
560
                break;
561
            }
562
            ++index;
563
            id += String.fromCharCode(ch);
564
565
            // '\u' (char #92, char #117) denotes an escaped character.
566
            if (ch === 92) {
567
                id = id.substr(0, id.length - 1);
568
                if (source.charCodeAt(index) !== 117) {
569
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
570
                }
571
                ++index;
572
                ch = scanHexEscape('u');
573
                if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
574
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
575
                }
576
                id += ch;
577
            }
578
        }
579
580
        return id;
581
    }
582
583
    function getIdentifier() {
584
        var start, ch;
585
586
        start = index++;
587
        while (index < length) {
588
            ch = source.charCodeAt(index);
589
            if (ch === 92) {
590
                // Blackslash (char #92) marks Unicode escape sequence.
591
                index = start;
592
                return getEscapedIdentifier();
593
            }
594
            if (isIdentifierPart(ch)) {
595
                ++index;
596
            } else {
597
                break;
598
            }
599
        }
600
601
        return source.slice(start, index);
602
    }
603
604
    function scanIdentifier() {
605
        var start, id, type;
606
607
        start = index;
608
609
        // Backslash (char #92) starts an escaped character.
610
        id = (source.charCodeAt(index) === 92) ? getEscapedIdentifier() : getIdentifier();
611
612
        // There is no keyword or literal with only one character.
613
        // Thus, it must be an identifier.
614
        if (id.length === 1) {
615
            type = Token.Identifier;
616
        } else if (isKeyword(id)) {
617
            type = Token.Keyword;
618
        } else if (id === 'null') {
619
            type = Token.NullLiteral;
620
        } else if (id === 'true' || id === 'false') {
621
            type = Token.BooleanLiteral;
622
        } else {
623
            type = Token.Identifier;
624
        }
625
626
        return {
627
            type: type,
628
            value: id,
629
            lineNumber: lineNumber,
630
            lineStart: lineStart,
631
            range: [start, index]
632
        };
633
    }
634
635
636
    // 7.7 Punctuators
637
638
    function scanPunctuator() {
639
        var start = index,
640
            code = source.charCodeAt(index),
641
            code2,
642
            ch1 = source[index],
643
            ch2,
644
            ch3,
645
            ch4;
646
647
        switch (code) {
648
649
        // Check for most common single-character punctuators.
650
        case 46:   // . dot
651
        case 40:   // ( open bracket
652
        case 41:   // ) close bracket
653
        case 59:   // ; semicolon
654
        case 44:   // , comma
655
        case 123:  // { open curly brace
656
        case 125:  // } close curly brace
657
        case 91:   // [
658
        case 93:   // ]
659
        case 58:   // :
660
        case 63:   // ?
661
        case 126:  // ~
662
            ++index;
663
            if (extra.tokenize) {
664
                if (code === 40) {
665
                    extra.openParenToken = extra.tokens.length;
666
                } else if (code === 123) {
667
                    extra.openCurlyToken = extra.tokens.length;
668
                }
669
            }
670
            return {
671
                type: Token.Punctuator,
672
                value: String.fromCharCode(code),
673
                lineNumber: lineNumber,
674
                lineStart: lineStart,
675
                range: [start, index]
676
            };
677
678
        default:
679
            code2 = source.charCodeAt(index + 1);
680
681
            // '=' (char #61) marks an assignment or comparison operator.
682
            if (code2 === 61) {
683
                switch (code) {
684
                case 37:  // %
685
                case 38:  // &
686
                case 42:  // *:
687
                case 43:  // +
688
                case 45:  // -
689
                case 47:  // /
690
                case 60:  // <
691
                case 62:  // >
692
                case 94:  // ^
693
                case 124: // |
694
                    index += 2;
695
                    return {
696
                        type: Token.Punctuator,
697
                        value: String.fromCharCode(code) + String.fromCharCode(code2),
698
                        lineNumber: lineNumber,
699
                        lineStart: lineStart,
700
                        range: [start, index]
701
                    };
702
703
                case 33: // !
704
                case 61: // =
705
                    index += 2;
706
707
                    // !== and ===
708
                    if (source.charCodeAt(index) === 61) {
709
                        ++index;
710
                    }
711
                    return {
712
                        type: Token.Punctuator,
713
                        value: source.slice(start, index),
714
                        lineNumber: lineNumber,
715
                        lineStart: lineStart,
716
                        range: [start, index]
717
                    };
718
                default:
719
                    break;
720
                }
721
            }
722
            break;
723
        }
724
725
        // Peek more characters.
726
727
        ch2 = source[index + 1];
728
        ch3 = source[index + 2];
729
        ch4 = source[index + 3];
730
731
        // 4-character punctuator: >>>=
732
733
        if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
734
            if (ch4 === '=') {
735
                index += 4;
736
                return {
737
                    type: Token.Punctuator,
738
                    value: '>>>=',
739
                    lineNumber: lineNumber,
740
                    lineStart: lineStart,
741
                    range: [start, index]
742
                };
743
            }
744
        }
745
746
        // 3-character punctuators: === !== >>> <<= >>=
747
748
        if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
749
            index += 3;
750
            return {
751
                type: Token.Punctuator,
752
                value: '>>>',
753
                lineNumber: lineNumber,
754
                lineStart: lineStart,
755
                range: [start, index]
756
            };
757
        }
758
759
        if (ch1 === '<' && ch2 === '<' && ch3 === '=') {
760
            index += 3;
761
            return {
762
                type: Token.Punctuator,
763
                value: '<<=',
764
                lineNumber: lineNumber,
765
                lineStart: lineStart,
766
                range: [start, index]
767
            };
768
        }
769
770
        if (ch1 === '>' && ch2 === '>' && ch3 === '=') {
771
            index += 3;
772
            return {
773
                type: Token.Punctuator,
774
                value: '>>=',
775
                lineNumber: lineNumber,
776
                lineStart: lineStart,
777
                range: [start, index]
778
            };
779
        }
780
781
        // Other 2-character punctuators: ++ -- << >> && ||
782
783
        if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {
784
            index += 2;
785
            return {
786
                type: Token.Punctuator,
787
                value: ch1 + ch2,
788
                lineNumber: lineNumber,
789
                lineStart: lineStart,
790
                range: [start, index]
791
            };
792
        }
793
794
        if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
795
            ++index;
796
            return {
797
                type: Token.Punctuator,
798
                value: ch1,
799
                lineNumber: lineNumber,
800
                lineStart: lineStart,
801
                range: [start, index]
802
            };
803
        }
804
805
        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
806
    }
807
808
    // 7.8.3 Numeric Literals
809
810
    function scanHexLiteral(start) {
811
        var number = '';
812
813
        while (index < length) {
814
            if (!isHexDigit(source[index])) {
815
                break;
816
            }
817
            number += source[index++];
818
        }
819
820
        if (number.length === 0) {
821
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
822
        }
823
824
        if (isIdentifierStart(source.charCodeAt(index))) {
825
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
826
        }
827
828
        return {
829
            type: Token.NumericLiteral,
830
            value: parseInt('0x' + number, 16),
831
            lineNumber: lineNumber,
832
            lineStart: lineStart,
833
            range: [start, index]
834
        };
835
    }
836
837
    function scanOctalLiteral(start) {
838
        var number = '0' + source[index++];
839
        while (index < length) {
840
            if (!isOctalDigit(source[index])) {
841
                break;
842
            }
843
            number += source[index++];
844
        }
845
846
        if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
847
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
848
        }
849
850
        return {
851
            type: Token.NumericLiteral,
852
            value: parseInt(number, 8),
853
            octal: true,
854
            lineNumber: lineNumber,
855
            lineStart: lineStart,
856
            range: [start, index]
857
        };
858
    }
859
860
    function scanNumericLiteral() {
861
        var number, start, ch;
862
863
        ch = source[index];
864
        assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
865
            'Numeric literal must start with a decimal digit or a decimal point');
866
867
        start = index;
868
        number = '';
869
        if (ch !== '.') {
870
            number = source[index++];
871
            ch = source[index];
872
873
            // Hex number starts with '0x'.
874
            // Octal number starts with '0'.
875
            if (number === '0') {
876
                if (ch === 'x' || ch === 'X') {
877
                    ++index;
878
                    return scanHexLiteral(start);
879
                }
880
                if (isOctalDigit(ch)) {
881
                    return scanOctalLiteral(start);
882
                }
883
884
                // decimal number starts with '0' such as '09' is illegal.
885
                if (ch && isDecimalDigit(ch.charCodeAt(0))) {
886
                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
887
                }
888
            }
889
890
            while (isDecimalDigit(source.charCodeAt(index))) {
891
                number += source[index++];
892
            }
893
            ch = source[index];
894
        }
895
896
        if (ch === '.') {
897
            number += source[index++];
898
            while (isDecimalDigit(source.charCodeAt(index))) {
899
                number += source[index++];
900
            }
901
            ch = source[index];
902
        }
903
904
        if (ch === 'e' || ch === 'E') {
905
            number += source[index++];
906
907
            ch = source[index];
908
            if (ch === '+' || ch === '-') {
909
                number += source[index++];
910
            }
911
            if (isDecimalDigit(source.charCodeAt(index))) {
912
                while (isDecimalDigit(source.charCodeAt(index))) {
913
                    number += source[index++];
914
                }
915
            } else {
916
                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
917
            }
918
        }
919
920
        if (isIdentifierStart(source.charCodeAt(index))) {
921
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
922
        }
923
924
        return {
925
            type: Token.NumericLiteral,
926
            value: parseFloat(number),
927
            lineNumber: lineNumber,
928
            lineStart: lineStart,
929
            range: [start, index]
930
        };
931
    }
932
933
    // 7.8.4 String Literals
934
935
    function scanStringLiteral() {
936
        var str = '', quote, start, ch, code, unescaped, restore, octal = false;
937
938
        quote = source[index];
939
        assert((quote === '\'' || quote === '"'),
940
            'String literal must starts with a quote');
941
942
        start = index;
943
        ++index;
944
945
        while (index < length) {
946
            ch = source[index++];
947
948
            if (ch === quote) {
949
                quote = '';
950
                break;
951
            } else if (ch === '\\') {
952
                ch = source[index++];
953
                if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
954
                    switch (ch) {
955
                    case 'n':
956
                        str += '\n';
957
                        break;
958
                    case 'r':
959
                        str += '\r';
960
                        break;
961
                    case 't':
962
                        str += '\t';
963
                        break;
964
                    case 'u':
965
                    case 'x':
966
                        restore = index;
967
                        unescaped = scanHexEscape(ch);
968
                        if (unescaped) {
969
                            str += unescaped;
970
                        } else {
971
                            index = restore;
972
                            str += ch;
973
                        }
974
                        break;
975
                    case 'b':
976
                        str += '\b';
977
                        break;
978
                    case 'f':
979
                        str += '\f';
980
                        break;
981
                    case 'v':
982
                        str += '\x0B';
983
                        break;
984
985
                    default:
986
                        if (isOctalDigit(ch)) {
987
                            code = '01234567'.indexOf(ch);
988
989
                            // \0 is not octal escape sequence
990
                            if (code !== 0) {
991
                                octal = true;
992
                            }
993
994
                            if (index < length && isOctalDigit(source[index])) {
995
                                octal = true;
996
                                code = code * 8 + '01234567'.indexOf(source[index++]);
997
998
                                // 3 digits are only allowed when string starts
999
                                // with 0, 1, 2, 3
1000
                                if ('0123'.indexOf(ch) >= 0 &&
1001
                                        index < length &&
1002
                                        isOctalDigit(source[index])) {
1003
                                    code = code * 8 + '01234567'.indexOf(source[index++]);
1004
                                }
1005
                            }
1006
                            str += String.fromCharCode(code);
1007
                        } else {
1008
                            str += ch;
1009
                        }
1010
                        break;
1011
                    }
1012
                } else {
1013
                    ++lineNumber;
1014
                    if (ch ===  '\r' && source[index] === '\n') {
1015
                        ++index;
1016
                    }
1017
                }
1018
            } else if (isLineTerminator(ch.charCodeAt(0))) {
1019
                break;
1020
            } else {
1021
                str += ch;
1022
            }
1023
        }
1024
1025
        if (quote !== '') {
1026
            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
1027
        }
1028
1029
        return {
1030
            type: Token.StringLiteral,
1031
            value: str,
1032
            octal: octal,
1033
            lineNumber: lineNumber,
1034
            lineStart: lineStart,
1035
            range: [start, index]
1036
        };
1037
    }
1038
1039
    function scanRegExp() {
1040
        var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false;
1041
1042
        lookahead = null;
1043
        skipComment();
1044
1045
        start = index;
1046
        ch = source[index];
1047
        assert(ch === '/', 'Regular expression literal must start with a slash');
1048
        str = source[index++];
1049
1050
        while (index < length) {
1051
            ch = source[index++];
1052
            str += ch;
1053
            if (ch === '\\') {
1054
                ch = source[index++];
1055
                // ECMA-262 7.8.5
1056
                if (isLineTerminator(ch.charCodeAt(0))) {
1057
                    throwError({}, Messages.UnterminatedRegExp);
1058
                }
1059
                str += ch;
1060
            } else if (isLineTerminator(ch.charCodeAt(0))) {
1061
                throwError({}, Messages.UnterminatedRegExp);
1062
            } else if (classMarker) {
1063
                if (ch === ']') {
1064
                    classMarker = false;
1065
                }
1066
            } else {
1067
                if (ch === '/') {
1068
                    terminated = true;
1069
                    break;
1070
                } else if (ch === '[') {
1071
                    classMarker = true;
1072
                }
1073
            }
1074
        }
1075
1076
        if (!terminated) {
1077
            throwError({}, Messages.UnterminatedRegExp);
1078
        }
1079
1080
        // Exclude leading and trailing slash.
1081
        pattern = str.substr(1, str.length - 2);
1082
1083
        flags = '';
1084
        while (index < length) {
1085
            ch = source[index];
1086
            if (!isIdentifierPart(ch.charCodeAt(0))) {
1087
                break;
1088
            }
1089
1090
            ++index;
1091
            if (ch === '\\' && index < length) {
1092
                ch = source[index];
1093
                if (ch === 'u') {
1094
                    ++index;
1095
                    restore = index;
1096
                    ch = scanHexEscape('u');
1097
                    if (ch) {
1098
                        flags += ch;
1099
                        for (str += '\\u'; restore < index; ++restore) {
1100
                            str += source[restore];
1101
                        }
1102
                    } else {
1103
                        index = restore;
1104
                        flags += 'u';
1105
                        str += '\\u';
1106
                    }
1107
                } else {
1108
                    str += '\\';
1109
                }
1110
            } else {
1111
                flags += ch;
1112
                str += ch;
1113
            }
1114
        }
1115
1116
        try {
1117
            value = new RegExp(pattern, flags);
1118
        } catch (e) {
1119
            throwError({}, Messages.InvalidRegExp);
1120
        }
1121
1122
1123
1124
        if (extra.tokenize) {
1125
            return {
1126
                type: Token.RegularExpression,
1127
                value: value,
1128
                lineNumber: lineNumber,
1129
                lineStart: lineStart,
1130
                range: [start, index]
1131
            };
1132
        }
1133
        return {
1134
            literal: str,
1135
            value: value,
1136
            range: [start, index]
1137
        };
1138
    }
1139
1140
    function collectRegex() {
1141
        var pos, loc, regex, token;
1142
1143
        skipComment();
1144
1145
        pos = index;
1146
        loc = {
1147
            start: {
1148
                line: lineNumber,
1149
                column: index - lineStart
1150
            }
1151
        };
1152
1153
        regex = scanRegExp();
1154
        loc.end = {
1155
            line: lineNumber,
1156
            column: index - lineStart
1157
        };
1158
1159
        if (!extra.tokenize) {
1160
            // Pop the previous token, which is likely '/' or '/='
1161
            if (extra.tokens.length > 0) {
1162
                token = extra.tokens[extra.tokens.length - 1];
1163
                if (token.range[0] === pos && token.type === 'Punctuator') {
1164
                    if (token.value === '/' || token.value === '/=') {
1165
                        extra.tokens.pop();
1166
                    }
1167
                }
1168
            }
1169
1170
            extra.tokens.push({
1171
                type: 'RegularExpression',
1172
                value: regex.literal,
1173
                range: [pos, index],
1174
                loc: loc
1175
            });
1176
        }
1177
1178
        return regex;
1179
    }
1180
1181
    function isIdentifierName(token) {
1182
        return token.type === Token.Identifier ||
1183
            token.type === Token.Keyword ||
1184
            token.type === Token.BooleanLiteral ||
1185
            token.type === Token.NullLiteral;
1186
    }
1187
1188
    function advanceSlash() {
1189
        var prevToken,
1190
            checkToken;
1191
        // Using the following algorithm:
1192
        // https://github.com/mozilla/sweet.js/wiki/design
1193
        prevToken = extra.tokens[extra.tokens.length - 1];
1194
        if (!prevToken) {
1195
            // Nothing before that: it cannot be a division.
1196
            return collectRegex();
1197
        }
1198
        if (prevToken.type === 'Punctuator') {
1199
            if (prevToken.value === ')') {
1200
                checkToken = extra.tokens[extra.openParenToken - 1];
1201
                if (checkToken &&
1202
                        checkToken.type === 'Keyword' &&
1203
                        (checkToken.value === 'if' ||
1204
                         checkToken.value === 'while' ||
1205
                         checkToken.value === 'for' ||
1206
                         checkToken.value === 'with')) {
1207
                    return collectRegex();
1208
                }
1209
                return scanPunctuator();
1210
            }
1211
            if (prevToken.value === '}') {
1212
                // Dividing a function by anything makes little sense,
1213
                // but we have to check for that.
1214
                if (extra.tokens[extra.openCurlyToken - 3] &&
1215
                        extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
1216
                    // Anonymous function.
1217
                    checkToken = extra.tokens[extra.openCurlyToken - 4];
1218
                    if (!checkToken) {
1219
                        return scanPunctuator();
1220
                    }
1221
                } else if (extra.tokens[extra.openCurlyToken - 4] &&
1222
                        extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
1223
                    // Named function.
1224
                    checkToken = extra.tokens[extra.openCurlyToken - 5];
1225
                    if (!checkToken) {
1226
                        return collectRegex();
1227
                    }
1228
                } else {
1229
                    return scanPunctuator();
1230
                }
1231
                // checkToken determines whether the function is
1232
                // a declaration or an expression.
1233
                if (FnExprTokens.indexOf(checkToken.value) >= 0) {
1234
                    // It is an expression.
1235
                    return scanPunctuator();
1236
                }
1237
                // It is a declaration.
1238
                return collectRegex();
1239
            }
1240
            return collectRegex();
1241
        }
1242
        if (prevToken.type === 'Keyword') {
1243
            return collectRegex();
1244
        }
1245
        return scanPunctuator();
1246
    }
1247
1248
    function advance() {
1249
        var ch;
1250
1251
        skipComment();
1252
1253
        if (index >= length) {
1254
            return {
1255
                type: Token.EOF,
1256
                lineNumber: lineNumber,
1257
                lineStart: lineStart,
1258
                range: [index, index]
1259
            };
1260
        }
1261
1262
        ch = source.charCodeAt(index);
1263
1264
        // Very common: ( and ) and ;
1265
        if (ch === 40 || ch === 41 || ch === 58) {
1266
            return scanPunctuator();
1267
        }
1268
1269
        // String literal starts with single quote (#39) or double quote (#34).
1270
        if (ch === 39 || ch === 34) {
1271
            return scanStringLiteral();
1272
        }
1273
1274
        if (isIdentifierStart(ch)) {
1275
            return scanIdentifier();
1276
        }
1277
1278
        // Dot (.) char #46 can also start a floating-point number, hence the need
1279
        // to check the next character.
1280
        if (ch === 46) {
1281
            if (isDecimalDigit(source.charCodeAt(index + 1))) {
1282
                return scanNumericLiteral();
1283
            }
1284
            return scanPunctuator();
1285
        }
1286
1287
        if (isDecimalDigit(ch)) {
1288
            return scanNumericLiteral();
1289
        }
1290
1291
        // Slash (/) char #47 can also start a regex.
1292
        if (extra.tokenize && ch === 47) {
1293
            return advanceSlash();
1294
        }
1295
1296
        return scanPunctuator();
1297
    }
1298
1299
    function collectToken() {
1300
        var start, loc, token, range, value;
1301
1302
        skipComment();
1303
        start = index;
1304
        loc = {
1305
            start: {
1306
                line: lineNumber,
1307
                column: index - lineStart
1308
            }
1309
        };
1310
1311
        token = advance();
1312
        loc.end = {
1313
            line: lineNumber,
1314
            column: index - lineStart
1315
        };
1316
1317
        if (token.type !== Token.EOF) {
1318
            range = [token.range[0], token.range[1]];
1319
            value = source.slice(token.range[0], token.range[1]);
1320
            extra.tokens.push({
1321
                type: TokenName[token.type],
1322
                value: value,
1323
                range: range,
1324
                loc: loc
1325
            });
1326
        }
1327
1328
        return token;
1329
    }
1330
1331
    function lex() {
1332
        var token;
1333
1334
        token = lookahead;
1335
        index = token.range[1];
1336
        lineNumber = token.lineNumber;
1337
        lineStart = token.lineStart;
1338
1339
        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
1340
1341
        index = token.range[1];
1342
        lineNumber = token.lineNumber;
1343
        lineStart = token.lineStart;
1344
1345
        return token;
1346
    }
1347
1348
    function peek() {
1349
        var pos, line, start;
1350
1351
        pos = index;
1352
        line = lineNumber;
1353
        start = lineStart;
1354
        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
1355
        index = pos;
1356
        lineNumber = line;
1357
        lineStart = start;
1358
    }
1359
1360
    SyntaxTreeDelegate = {
1361
1362
        name: 'SyntaxTree',
1363
1364
        markStart: function () {
1365
            if (extra.loc) {
1366
                state.markerStack.push(index - lineStart);
1367
                state.markerStack.push(lineNumber);
1368
            }
1369
            if (extra.range) {
1370
                state.markerStack.push(index);
1371
            }
1372
        },
1373
1374
        processComment: function (node) {
1375
            var i, attacher, pos, len, candidate;
1376
1377
            if (typeof node.type === 'undefined' || node.type === Syntax.Program) {
1378
                return;
1379
            }
1380
1381
            // Check for possible additional trailing comments.
1382
            peek();
1383
1384
            for (i = 0; i < extra.pendingComments.length; ++i) {
1385
                attacher = extra.pendingComments[i];
1386
                if (node.range[0] >= attacher.comment.range[1]) {
1387
                    candidate = attacher.leading;
1388
                    if (candidate) {
1389
                        pos = candidate.range[0];
1390
                        len = candidate.range[1] - pos;
1391
                        if (node.range[0] <= pos && (node.range[1] - node.range[0] >= len)) {
1392
                            attacher.leading = node;
1393
                        }
1394
                    } else {
1395
                        attacher.leading = node;
1396
                    }
1397
                }
1398
                if (node.range[1] <= attacher.comment.range[0]) {
1399
                    candidate = attacher.trailing;
1400
                    if (candidate) {
1401
                        pos = candidate.range[0];
1402
                        len = candidate.range[1] - pos;
1403
                        if (node.range[0] <= pos && (node.range[1] - node.range[0] >= len)) {
1404
                            attacher.trailing = node;
1405
                        }
1406
                    } else {
1407
                        attacher.trailing = node;
1408
                    }
1409
                }
1410
            }
1411
        },
1412
1413
        markEnd: function (node) {
1414
            if (extra.range) {
1415
                node.range = [state.markerStack.pop(), index];
1416
            }
1417
            if (extra.loc) {
1418
                node.loc = {
1419
                    start: {
1420
                        line: state.markerStack.pop(),
1421
                        column: state.markerStack.pop()
1422
                    },
1423
                    end: {
1424
                        line: lineNumber,
1425
                        column: index - lineStart
1426
                    }
1427
                };
1428
                this.postProcess(node);
1429
            }
1430
            if (extra.attachComment) {
1431
                this.processComment(node);
1432
            }
1433
            return node;
1434
        },
1435
1436
        markEndIf: function (node) {
1437
            // mamacdon: in tolerant mode, node passed to the delegate may be null
1438
            if (!node || node.range || node.loc) {
1439
                if (extra.loc) {
1440
                    state.markerStack.pop();
1441
                    state.markerStack.pop();
1442
                }
1443
                if (extra.range) {
1444
                    state.markerStack.pop();
1445
                }
1446
            } else {
1447
                this.markEnd(node);
1448
            }
1449
            return node;
1450
        },
1451
1452
        postProcess: function (node) {
1453
            if (extra.source) {
1454
                node.loc.source = extra.source;
1455
            }
1456
            return node;
1457
        },
1458
1459
        createArrayExpression: function (elements) {
1460
            return {
1461
                type: Syntax.ArrayExpression,
1462
                elements: elements
1463
            };
1464
        },
1465
1466
        createAssignmentExpression: function (operator, left, right) {
1467
            return {
1468
                type: Syntax.AssignmentExpression,
1469
                operator: operator,
1470
                left: left,
1471
                right: right
1472
            };
1473
        },
1474
1475
        createBinaryExpression: function (operator, left, right) {
1476
            var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression :
1477
                        Syntax.BinaryExpression;
1478
            return {
1479
                type: type,
1480
                operator: operator,
1481
                left: left,
1482
                right: right
1483
            };
1484
        },
1485
1486
        createBlockStatement: function (body) {
1487
            return {
1488
                type: Syntax.BlockStatement,
1489
                body: body
1490
            };
1491
        },
1492
1493
        createBreakStatement: function (label) {
1494
            return {
1495
                type: Syntax.BreakStatement,
1496
                label: label
1497
            };
1498
        },
1499
1500
        createCallExpression: function (callee, args) {
1501
            return {
1502
                type: Syntax.CallExpression,
1503
                callee: callee,
1504
                'arguments': args
1505
            };
1506
        },
1507
1508
        createCatchClause: function (param, body) {
1509
            return {
1510
                type: Syntax.CatchClause,
1511
                param: param,
1512
                body: body
1513
            };
1514
        },
1515
1516
        createConditionalExpression: function (test, consequent, alternate) {
1517
            return {
1518
                type: Syntax.ConditionalExpression,
1519
                test: test,
1520
                consequent: consequent,
1521
                alternate: alternate
1522
            };
1523
        },
1524
1525
        createContinueStatement: function (label) {
1526
            return {
1527
                type: Syntax.ContinueStatement,
1528
                label: label
1529
            };
1530
        },
1531
1532
        createDebuggerStatement: function () {
1533
            return {
1534
                type: Syntax.DebuggerStatement
1535
            };
1536
        },
1537
1538
        createDoWhileStatement: function (body, test) {
1539
            return {
1540
                type: Syntax.DoWhileStatement,
1541
                body: body,
1542
                test: test
1543
            };
1544
        },
1545
1546
        createEmptyStatement: function () {
1547
            return {
1548
                type: Syntax.EmptyStatement
1549
            };
1550
        },
1551
1552
        createExpressionStatement: function (expression) {
1553
            return {
1554
                type: Syntax.ExpressionStatement,
1555
                expression: expression
1556
            };
1557
        },
1558
1559
        createForStatement: function (init, test, update, body) {
1560
            return {
1561
                type: Syntax.ForStatement,
1562
                init: init,
1563
                test: test,
1564
                update: update,
1565
                body: body
1566
            };
1567
        },
1568
1569
        createForInStatement: function (left, right, body) {
1570
            return {
1571
                type: Syntax.ForInStatement,
1572
                left: left,
1573
                right: right,
1574
                body: body,
1575
                each: false
1576
            };
1577
        },
1578
1579
        createFunctionDeclaration: function (id, params, defaults, body) {
1580
            return {
1581
                type: Syntax.FunctionDeclaration,
1582
                id: id,
1583
                params: params,
1584
                defaults: defaults,
1585
                body: body,
1586
                rest: null,
1587
                generator: false,
1588
                expression: false
1589
            };
1590
        },
1591
1592
        createFunctionExpression: function (id, params, defaults, body) {
1593
            return {
1594
                type: Syntax.FunctionExpression,
1595
                id: id,
1596
                params: params,
1597
                defaults: defaults,
1598
                body: body,
1599
                rest: null,
1600
                generator: false,
1601
                expression: false
1602
            };
1603
        },
1604
1605
        createIdentifier: function (name) {
1606
            return {
1607
                type: Syntax.Identifier,
1608
                name: name
1609
            };
1610
        },
1611
1612
        createIfStatement: function (test, consequent, alternate) {
1613
            return {
1614
                type: Syntax.IfStatement,
1615
                test: test,
1616
                consequent: consequent,
1617
                alternate: alternate
1618
            };
1619
        },
1620
1621
        createLabeledStatement: function (label, body) {
1622
            return {
1623
                type: Syntax.LabeledStatement,
1624
                label: label,
1625
                body: body
1626
            };
1627
        },
1628
1629
        createLiteral: function (token) {
1630
            return {
1631
                type: Syntax.Literal,
1632
                value: token.value,
1633
                raw: source.slice(token.range[0], token.range[1])
1634
            };
1635
        },
1636
1637
        createMemberExpression: function (accessor, object, property) {
1638
            return {
1639
                type: Syntax.MemberExpression,
1640
                computed: accessor === '[',
1641
                object: object,
1642
                property: property
1643
            };
1644
        },
1645
1646
        createNewExpression: function (callee, args) {
1647
            return {
1648
                type: Syntax.NewExpression,
1649
                callee: callee,
1650
                'arguments': args
1651
            };
1652
        },
1653
1654
        createObjectExpression: function (properties) {
1655
            return {
1656
                type: Syntax.ObjectExpression,
1657
                properties: properties
1658
            };
1659
        },
1660
1661
        createPostfixExpression: function (operator, argument) {
1662
            return {
1663
                type: Syntax.UpdateExpression,
1664
                operator: operator,
1665
                argument: argument,
1666
                prefix: false
1667
            };
1668
        },
1669
1670
        createProgram: function (body) {
1671
            return {
1672
                type: Syntax.Program,
1673
                body: body
1674
            };
1675
        },
1676
1677
        createProperty: function (kind, key, value) {
1678
            return {
1679
                type: Syntax.Property,
1680
                key: key,
1681
                value: value,
1682
                kind: kind
1683
            };
1684
        },
1685
1686
        createReturnStatement: function (argument) {
1687
            return {
1688
                type: Syntax.ReturnStatement,
1689
                argument: argument
1690
            };
1691
        },
1692
1693
        createSequenceExpression: function (expressions) {
1694
            return {
1695
                type: Syntax.SequenceExpression,
1696
                expressions: expressions
1697
            };
1698
        },
1699
1700
        createSwitchCase: function (test, consequent) {
1701
            return {
1702
                type: Syntax.SwitchCase,
1703
                test: test,
1704
                consequent: consequent
1705
            };
1706
        },
1707
1708
        createSwitchStatement: function (discriminant, cases) {
1709
            return {
1710
                type: Syntax.SwitchStatement,
1711
                discriminant: discriminant,
1712
                cases: cases
1713
            };
1714
        },
1715
1716
        createThisExpression: function () {
1717
            return {
1718
                type: Syntax.ThisExpression
1719
            };
1720
        },
1721
1722
        createThrowStatement: function (argument) {
1723
            return {
1724
                type: Syntax.ThrowStatement,
1725
                argument: argument
1726
            };
1727
        },
1728
1729
        createTryStatement: function (block, guardedHandlers, handlers, finalizer) {
1730
            return {
1731
                type: Syntax.TryStatement,
1732
                block: block,
1733
                guardedHandlers: guardedHandlers,
1734
                handlers: handlers,
1735
                finalizer: finalizer
1736
            };
1737
        },
1738
1739
        createUnaryExpression: function (operator, argument) {
1740
            if (operator === '++' || operator === '--') {
1741
                return {
1742
                    type: Syntax.UpdateExpression,
1743
                    operator: operator,
1744
                    argument: argument,
1745
                    prefix: true
1746
                };
1747
            }
1748
            return {
1749
                type: Syntax.UnaryExpression,
1750
                operator: operator,
1751
                argument: argument,
1752
                prefix: true
1753
            };
1754
        },
1755
1756
        createVariableDeclaration: function (declarations, kind) {
1757
            return {
1758
                type: Syntax.VariableDeclaration,
1759
                declarations: declarations,
1760
                kind: kind
1761
            };
1762
        },
1763
1764
        createVariableDeclarator: function (id, init) {
1765
            return {
1766
                type: Syntax.VariableDeclarator,
1767
                id: id,
1768
                init: init
1769
            };
1770
        },
1771
1772
        createWhileStatement: function (test, body) {
1773
            return {
1774
                type: Syntax.WhileStatement,
1775
                test: test,
1776
                body: body
1777
            };
1778
        },
1779
1780
        createWithStatement: function (object, body) {
1781
            return {
1782
                type: Syntax.WithStatement,
1783
                object: object,
1784
                body: body
1785
            };
1786
        }
1787
    };
1788
1789
    // Return true if there is a line terminator before the next token.
1790
1791
    function peekLineTerminator() {
1792
        var pos, line, start, found;
1793
1794
        pos = index;
1795
        line = lineNumber;
1796
        start = lineStart;
1797
        skipComment();
1798
        found = lineNumber !== line;
1799
        index = pos;
1800
        lineNumber = line;
1801
        lineStart = start;
1802
1803
        return found;
1804
    }
1805
1806
    // Throw an exception
1807
1808
    function throwError(token, messageFormat) {
1809
        var error,
1810
            args = Array.prototype.slice.call(arguments, 2),
1811
            msg = messageFormat.replace(
1812
                /%(\d)/g,
1813
                function (whole, index) {
1814
                    assert(index < args.length, 'Message reference must be in range');
1815
                    return args[index];
1816
                }
1817
            );
1818
1819
        if (typeof token.lineNumber === 'number') {
1820
            error = new Error('Line ' + token.lineNumber + ': ' + msg);
1821
            error.index = token.range[0];
1822
            // mamacdon a09739e
1823
            // mamacdon @ 1.0.0 esprima.js:1198
1824
            error.end = token.range[1];
1825
            error.token = token.value;
1826
            error.lineNumber = token.lineNumber;
1827
            error.column = token.range[0] - lineStart + 1;
1828
        } else {
1829
            error = new Error('Line ' + lineNumber + ': ' + msg);
1830
            error.index = index;
1831
            error.lineNumber = lineNumber;
1832
            error.column = index - lineStart + 1;
1833
        }
1834
1835
        error.description = msg;
1836
        throw error;
1837
    }
1838
1839
    // mamacdon: in tolerant mode, records the error and returns undefined. If non tolerant, throws.
1840
    function throwErrorTolerant() {
1841
        try {
1842
            throwError.apply(null, arguments);
1843
        } catch (e) {
1844
            if (extra.errors) {
1845
                extra.errors.push(e);
1846
            } else {
1847
                throw e;
1848
            }
1849
        }
1850
    }
1851
1852
    // Throw an exception because of the token.
1853
1854
    function throwUnexpected(token) {
1855
        if (token.type === Token.EOF) {
1856
            throwError(token, Messages.UnexpectedEOS);
1857
        }
1858
1859
        if (token.type === Token.NumericLiteral) {
1860
            throwError(token, Messages.UnexpectedNumber);
1861
        }
1862
1863
        if (token.type === Token.StringLiteral) {
1864
            throwError(token, Messages.UnexpectedString);
1865
        }
1866
1867
        if (token.type === Token.Identifier) {
1868
            throwError(token, Messages.UnexpectedIdentifier);
1869
        }
1870
1871
        if (token.type === Token.Keyword) {
1872
            if (isFutureReservedWord(token.value)) {
1873
                throwError(token, Messages.UnexpectedReserved);
1874
            } else if (strict && isStrictModeReservedWord(token.value)) {
1875
                throwErrorTolerant(token, Messages.StrictReservedWord);
1876
            }
1877
            throwError(token, Messages.UnexpectedToken, token.value);
1878
        }
1879
1880
        // BooleanLiteral, NullLiteral, or Punctuator.
1881
        throwError(token, Messages.UnexpectedToken, token.value);
1882
    }
1883
1884
    // Expect the next token to match the specified punctuator.
1885
    // If not, an exception will be thrown.
1886
1887
    function expect(value) {
1888
        var token = lex();
1889
        if (token.type !== Token.Punctuator || token.value !== value) {
1890
            throwUnexpected(token);
1891
        }
1892
    }
1893
1894
    // Expect the next token to match the specified keyword.
1895
    // If not, an exception will be thrown.
1896
1897
    function expectKeyword(keyword) {
1898
        var token = lex();
1899
        if (token.type !== Token.Keyword || token.value !== keyword) {
1900
            throwUnexpected(token);
1901
        }
1902
    }
1903
1904
    // Return true if the next token matches the specified punctuator.
1905
1906
    function match(value) {
1907
        return lookahead.type === Token.Punctuator && lookahead.value === value;
1908
    }
1909
1910
    // Return true if the next token matches the specified keyword
1911
1912
    function matchKeyword(keyword) {
1913
        return lookahead.type === Token.Keyword && lookahead.value === keyword;
1914
    }
1915
1916
    // Return true if the next token is an assignment operator
1917
1918
    function matchAssign() {
1919
        var op;
1920
1921
        if (lookahead.type !== Token.Punctuator) {
1922
            return false;
1923
        }
1924
        op = lookahead.value;
1925
        return op === '=' ||
1926
            op === '*=' ||
1927
            op === '/=' ||
1928
            op === '%=' ||
1929
            op === '+=' ||
1930
            op === '-=' ||
1931
            op === '<<=' ||
1932
            op === '>>=' ||
1933
            op === '>>>=' ||
1934
            op === '&=' ||
1935
            op === '^=' ||
1936
            op === '|=';
1937
    }
1938
1939
    function consumeSemicolon() {
1940
        var line;
1941
1942
        // Catch the very common case first: immediately a semicolon (char #59).
1943
        if (source.charCodeAt(index) === 59) {
1944
            lex();
1945
            return;
1946
        }
1947
1948
        line = lineNumber;
1949
        skipComment();
1950
        if (lineNumber !== line) {
1951
            return;
1952
        }
1953
1954
        if (match(';')) {
1955
            lex();
1956
            return;
1957
        }
1958
1959
        if (lookahead.type !== Token.EOF && !match('}')) {
1960
        	var badToken = lookahead;
1961
        	if (extra.errors) {
1962
                rewind(); // mutates lookahead
1963
            }
1964
            throwUnexpected(badToken);
1965
        }
1966
    }
1967
1968
    // Return true if provided expression is LeftHandSideExpression
1969
1970
    function isLeftHandSide(expr) {
1971
        return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
1972
    }
1973
1974
    // 11.1.4 Array Initialiser
1975
1976
    function parseArrayInitialiser() {
1977
        var elements = [];
1978
1979
        expect('[');
1980
1981
        while (!match(']')) {
1982
            if (match(',')) {
1983
                lex();
1984
                elements.push(null);
1985
            } else {
1986
                elements.push(parseAssignmentExpression());
1987
1988
                if (!match(']')) {
1989
                    expect(',');
1990
                }
1991
            }
1992
        }
1993
1994
        expect(']');
1995
1996
        return delegate.createArrayExpression(elements);
1997
    }
1998
1999
    // 11.1.5 Object Initialiser
2000
2001
    function parsePropertyFunction(param, first) {
2002
        var previousStrict, body;
2003
2004
        previousStrict = strict;
2005
        skipComment();
2006
        delegate.markStart();
2007
        body = parseFunctionSourceElements();
2008
        if (first && strict && isRestrictedWord(param[0].name)) {
2009
            throwErrorTolerant(first, Messages.StrictParamName);
2010
        }
2011
        strict = previousStrict;
2012
        return delegate.markEnd(delegate.createFunctionExpression(null, param, [], body));
2013
    }
2014
2015
    function parseObjectPropertyKey() {
2016
        var token;
2017
2018
        skipComment();
2019
        delegate.markStart();
2020
        token = lex();
2021
2022
        // Note: This function is called only from parseObjectProperty(), where
2023
        // EOF and Punctuator tokens are already filtered out.
2024
2025
        if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
2026
            if (strict && token.octal) {
2027
                throwErrorTolerant(token, Messages.StrictOctalLiteral);
2028
            }
2029
            return delegate.markEnd(delegate.createLiteral(token));
2030
        }
2031
2032
        return delegate.markEnd(delegate.createIdentifier(token.value));
2033
    }
2034
2035
    function parseObjectProperty() {
2036
        var token, key, id, value, param;
2037
2038
        token = lookahead;
2039
        skipComment();
2040
        delegate.markStart();
2041
2042
        if (token.type === Token.Identifier) {
2043
2044
            id = parseObjectPropertyKey();
2045
2046
            // Property Assignment: Getter and Setter.
2047
2048
            if (token.value === 'get' && !match(':')) {
2049
                key = parseObjectPropertyKey();
2050
                expect('(');
2051
                expect(')');
2052
                value = parsePropertyFunction([]);
2053
                return delegate.markEnd(delegate.createProperty('get', key, value));
2054
            }
2055
            if (token.value === 'set' && !match(':')) {
2056
                key = parseObjectPropertyKey();
2057
                expect('(');
2058
                token = lookahead;
2059
                if (token.type !== Token.Identifier) {
2060
                    expect(')');
2061
                    throwErrorTolerant(token, Messages.UnexpectedToken, token.value);
2062
                    value = parsePropertyFunction([]);
2063
                } else {
2064
                    param = [ parseVariableIdentifier() ];
2065
                    expect(')');
2066
                    value = parsePropertyFunction(param, token);
2067
                }
2068
                return delegate.markEnd(delegate.createProperty('set', key, value));
2069
            }
2070
            expect(':');
2071
            value = parseAssignmentExpression();
2072
            return delegate.markEnd(delegate.createProperty('init', id, value));
2073
        }
2074
        if (token.type === Token.EOF || token.type === Token.Punctuator) {
2075
            throwUnexpected(token);
2076
        } else {
2077
            key = parseObjectPropertyKey();
2078
            expect(':');
2079
            value = parseAssignmentExpression();
2080
            return delegate.markEnd(delegate.createProperty('init', key, value));
2081
        }
2082
    }
2083
2084
    function parseObjectInitialiser() {
2085
        var properties = [], property, name, key, kind, map = {}, toString = String;
2086
2087
        expect('{');
2088
2089
        while (!match('}')) {
2090
            property = parseObjectProperty();
2091
2092
            if (property.key.type === Syntax.Identifier) {
2093
                name = property.key.name;
2094
            } else {
2095
                name = toString(property.key.value);
2096
            }
2097
            kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
2098
2099
            key = '$' + name;
2100
            if (Object.prototype.hasOwnProperty.call(map, key)) {
2101
                if (map[key] === PropertyKind.Data) {
2102
                    if (strict && kind === PropertyKind.Data) {
2103
                        throwErrorTolerant({}, Messages.StrictDuplicateProperty);
2104
                    } else if (kind !== PropertyKind.Data) {
2105
                        throwErrorTolerant({}, Messages.AccessorDataProperty);
2106
                    }
2107
                } else {
2108
                    if (kind === PropertyKind.Data) {
2109
                        throwErrorTolerant({}, Messages.AccessorDataProperty);
2110
                    } else if (map[key] & kind) {
2111
                        throwErrorTolerant({}, Messages.AccessorGetSet);
2112
                    }
2113
                }
2114
                map[key] |= kind;
2115
            } else {
2116
                map[key] = kind;
2117
            }
2118
2119
            properties.push(property);
2120
2121
            if (!match('}')) {
2122
                expect(',');
2123
            }
2124
        }
2125
2126
        expect('}');
2127
2128
        return delegate.createObjectExpression(properties);
2129
    }
2130
2131
    // 11.1.6 The Grouping Operator
2132
2133
    function parseGroupExpression() {
2134
        var expr;
2135
2136
        expect('(');
2137
2138
        expr = parseExpression();
2139
2140
        expect(')');
2141
2142
        return expr;
2143
    }
2144
2145
2146
    // 11.1 Primary Expressions
2147
2148
    function parsePrimaryExpression() {
2149
        var type, token, expr;
2150
2151
        if (match('(')) {
2152
            return parseGroupExpression();
2153
        }
2154
2155
        type = lookahead.type;
2156
        delegate.markStart();
2157
2158
        if (type === Token.Identifier) {
2159
            expr =  delegate.createIdentifier(lex().value);
2160
        } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
2161
            if (strict && lookahead.octal) {
2162
                throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
2163
            }
2164
            expr = delegate.createLiteral(lex());
2165
        } else if (type === Token.Keyword) {
2166
            if (matchKeyword('this')) {
2167
                lex();
2168
                expr = delegate.createThisExpression();
2169
            } else if (matchKeyword('function')) {
2170
                expr = parseFunctionExpression();
2171
            }
2172
        } else if (type === Token.BooleanLiteral) {
2173
            token = lex();
2174
            token.value = (token.value === 'true');
2175
            expr = delegate.createLiteral(token);
2176
        } else if (type === Token.NullLiteral) {
2177
            token = lex();
2178
            token.value = null;
2179
            expr = delegate.createLiteral(token);
2180
        } else if (match('[')) {
2181
            expr = parseArrayInitialiser();
2182
        } else if (match('{')) {
2183
            expr = parseObjectInitialiser();
2184
        } else if (match('/') || match('/=')) {
2185
            if (typeof extra.tokens !== 'undefined') {
2186
                expr = delegate.createLiteral(collectRegex());
2187
            } else {
2188
                expr = delegate.createLiteral(scanRegExp());
2189
            }
2190
            peek();
2191
        }
2192
2193
        if (expr) {
2194
            return delegate.markEnd(expr);
2195
        }
2196
2197
        return throwUnexpected(lex());
2198
    }
2199
2200
    // 11.2 Left-Hand-Side Expressions
2201
2202
    // mamacdon 1420b19
2203
    function parseArguments() {
2204
        var args = [];
2205
2206
        expect('(');
2207
2208
        if (!match(')')) {
2209
            while (index < length) {
2210
                args.push(parseAssignmentExpression());
2211
                if (match(')')) {
2212
                    break;
2213
                }
2214
                try {
2215
                    expect(',');
2216
                } catch (e) {
2217
                    if (extra.errors) {
2218
                        // pretend the argument list is done
2219
                        pushError(e);
2220
                        break;
2221
                    } else {
2222
                        throw e;
2223
                    }
2224
                }
2225
            }
2226
        }
2227
2228
		try {
2229
            expect(')');
2230
        } catch (e) {
2231
            if (extra.errors) {   
2232
                // soldier on...
2233
                pushError(e);
2234
            } else {
2235
                throw e;
2236
            }
2237
        }
2238
2239
        return args;
2240
    }
2241
2242
    function parseNonComputedProperty() {
2243
        var token;
2244
2245
		if (lookahead.lineNumber !== lineNumber) {
2246
			// Token giving our identifier name lies on the following line, so go there before marking start
2247
			index = lookahead.lineStart;
2248
		}
2249
        delegate.markStart();
2250
        token = lex();
2251
2252
        if (!isIdentifierName(token)) {
2253
        	if (extra.errors) {
2254
                attemptRecoveryNonComputedProperty(token);
2255
            }
2256
            throwUnexpected(token);
2257
            // return null; // unecessary
2258
        }
2259
2260
        return delegate.markEnd(delegate.createIdentifier(token.value));
2261
    }
2262
2263
    function parseNonComputedMember() {
2264
        expect('.');
2265
2266
        return parseNonComputedProperty();
2267
    }
2268
2269
    function parseComputedMember() {
2270
        var expr;
2271
2272
        expect('[');
2273
2274
        expr = parseExpression();
2275
2276
        expect(']');
2277
2278
        return expr;
2279
    }
2280
2281
    function parseNewExpression() {
2282
        var callee, args;
2283
2284
        delegate.markStart();
2285
        expectKeyword('new');
2286
        callee = parseLeftHandSideExpression();
2287
        args = match('(') ? parseArguments() : [];
2288
2289
        return delegate.markEnd(delegate.createNewExpression(callee, args));
2290
    }
2291
2292
    function parseLeftHandSideExpressionAllowCall() {
2293
        var marker, previousAllowIn, expr, args, property;
2294
2295
        marker = createLocationMarker();
2296
2297
        previousAllowIn = state.allowIn;
2298
        state.allowIn = true;
2299
        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
2300
        state.allowIn = previousAllowIn;
2301
2302
        while (match('.') || match('[') || match('(')) {
2303
            if (match('(')) {
2304
                args = parseArguments();
2305
                expr = delegate.createCallExpression(expr, args);
2306
            } else if (match('[')) {
2307
                property = parseComputedMember();
2308
                expr = delegate.createMemberExpression('[', expr, property);
2309
            } else {
2310
                property = parseNonComputedMember();
2311
                expr = delegate.createMemberExpression('.', expr, property);
2312
            }
2313
            if (marker) {
2314
                marker.end();
2315
                marker.apply(expr);
2316
            }
2317
        }
2318
2319
        return expr;
2320
    }
2321
2322
    function parseLeftHandSideExpression() {
2323
        var marker, previousAllowIn, expr, property;
2324
2325
        marker = createLocationMarker();
2326
2327
        previousAllowIn = state.allowIn;
2328
        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
2329
        state.allowIn = previousAllowIn;
2330
2331
        while (match('.') || match('[')) {
2332
            if (match('[')) {
2333
                property = parseComputedMember();
2334
                expr = delegate.createMemberExpression('[', expr, property);
2335
            } else {
2336
                property = parseNonComputedMember();
2337
                expr = delegate.createMemberExpression('.', expr, property);
2338
            }
2339
            if (marker) {
2340
                marker.end();
2341
                marker.apply(expr);
2342
            }
2343
        }
2344
2345
        return expr;
2346
    }
2347
2348
    // 11.3 Postfix Expressions
2349
2350
    function parsePostfixExpression() {
2351
        var expr, token;
2352
2353
        delegate.markStart();
2354
        expr = parseLeftHandSideExpressionAllowCall();
2355
2356
        if (lookahead.type === Token.Punctuator) {
2357
            if ((match('++') || match('--')) && !peekLineTerminator()) {
2358
                // 11.3.1, 11.3.2
2359
                if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
2360
                    throwErrorTolerant({}, Messages.StrictLHSPostfix);
2361
                }
2362
2363
                if (!isLeftHandSide(expr)) {
2364
                    throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2365
                }
2366
2367
                token = lex();
2368
                expr = delegate.createPostfixExpression(token.value, expr);
2369
            }
2370
        }
2371
2372
        return delegate.markEndIf(expr);
2373
    }
2374
2375
    // 11.4 Unary Operators
2376
2377
    function parseUnaryExpression() {
2378
        var token, expr;
2379
2380
        delegate.markStart();
2381
2382
        if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
2383
            expr = parsePostfixExpression();
2384
        } else if (match('++') || match('--')) {
2385
            token = lex();
2386
            expr = parseUnaryExpression();
2387
            // 11.4.4, 11.4.5
2388
            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
2389
                throwErrorTolerant({}, Messages.StrictLHSPrefix);
2390
            }
2391
2392
            if (!isLeftHandSide(expr)) {
2393
                throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2394
            }
2395
2396
            expr = delegate.createUnaryExpression(token.value, expr);
2397
        } else if (match('+') || match('-') || match('~') || match('!')) {
2398
            token = lex();
2399
            expr = parseUnaryExpression();
2400
            expr = delegate.createUnaryExpression(token.value, expr);
2401
        } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
2402
            token = lex();
2403
            expr = parseUnaryExpression();
2404
            expr = delegate.createUnaryExpression(token.value, expr);
2405
            if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
2406
                throwErrorTolerant({}, Messages.StrictDelete);
2407
            }
2408
        } else {
2409
            expr = parsePostfixExpression();
2410
        }
2411
2412
        return delegate.markEndIf(expr);
2413
    }
2414
2415
    function binaryPrecedence(token, allowIn) {
2416
        var prec = 0;
2417
2418
        if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
2419
            return 0;
2420
        }
2421
2422
        switch (token.value) {
2423
        case '||':
2424
            prec = 1;
2425
            break;
2426
2427
        case '&&':
2428
            prec = 2;
2429
            break;
2430
2431
        case '|':
2432
            prec = 3;
2433
            break;
2434
2435
        case '^':
2436
            prec = 4;
2437
            break;
2438
2439
        case '&':
2440
            prec = 5;
2441
            break;
2442
2443
        case '==':
2444
        case '!=':
2445
        case '===':
2446
        case '!==':
2447
            prec = 6;
2448
            break;
2449
2450
        case '<':
2451
        case '>':
2452
        case '<=':
2453
        case '>=':
2454
        case 'instanceof':
2455
            prec = 7;
2456
            break;
2457
2458
        case 'in':
2459
            prec = allowIn ? 7 : 0;
2460
            break;
2461
2462
        case '<<':
2463
        case '>>':
2464
        case '>>>':
2465
            prec = 8;
2466
            break;
2467
2468
        case '+':
2469
        case '-':
2470
            prec = 9;
2471
            break;
2472
2473
        case '*':
2474
        case '/':
2475
        case '%':
2476
            prec = 11;
2477
            break;
2478
2479
        default:
2480
            break;
2481
        }
2482
2483
        return prec;
2484
    }
2485
2486
    // 11.5 Multiplicative Operators
2487
    // 11.6 Additive Operators
2488
    // 11.7 Bitwise Shift Operators
2489
    // 11.8 Relational Operators
2490
    // 11.9 Equality Operators
2491
    // 11.10 Binary Bitwise Operators
2492
    // 11.11 Binary Logical Operators
2493
2494
    function parseBinaryExpression() {
2495
        var marker, markers, expr, token, prec, stack, right, operator, left, i;
2496
2497
        marker = createLocationMarker();
2498
        left = parseUnaryExpression();
2499
2500
        token = lookahead;
2501
        prec = binaryPrecedence(token, state.allowIn);
2502
        if (prec === 0) {
2503
            return left;
2504
        }
2505
        token.prec = prec;
2506
        lex();
2507
2508
        markers = [marker, createLocationMarker()];
2509
        right = parseUnaryExpression();
2510
2511
        stack = [left, token, right];
2512
2513
        while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) {
2514
2515
            // Reduce: make a binary expression from the three topmost entries.
2516
            while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
2517
                right = stack.pop();
2518
                operator = stack.pop().value;
2519
                left = stack.pop();
2520
                expr = delegate.createBinaryExpression(operator, left, right);
2521
                markers.pop();
2522
                marker = markers.pop();
2523
                if (marker) {
2524
                    marker.end();
2525
                    marker.apply(expr);
2526
                }
2527
                stack.push(expr);
2528
                markers.push(marker);
2529
            }
2530
2531
            // Shift.
2532
            token = lex();
2533
            token.prec = prec;
2534
            stack.push(token);
2535
            markers.push(createLocationMarker());
2536
            expr = parseUnaryExpression();
2537
            stack.push(expr);
2538
        }
2539
2540
        // Final reduce to clean-up the stack.
2541
        i = stack.length - 1;
2542
        expr = stack[i];
2543
        markers.pop();
2544
        while (i > 1) {
2545
            expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
2546
            i -= 2;
2547
            marker = markers.pop();
2548
            if (marker) {
2549
                marker.end();
2550
                marker.apply(expr);
2551
            }
2552
        }
2553
2554
        return expr;
2555
    }
2556
2557
2558
    // 11.12 Conditional Operator
2559
2560
    function parseConditionalExpression() {
2561
        var expr, previousAllowIn, consequent, alternate;
2562
2563
        delegate.markStart();
2564
        expr = parseBinaryExpression();
2565
2566
        if (match('?')) {
2567
            lex();
2568
            previousAllowIn = state.allowIn;
2569
            state.allowIn = true;
2570
            consequent = parseAssignmentExpression();
2571
            state.allowIn = previousAllowIn;
2572
            expect(':');
2573
            alternate = parseAssignmentExpression();
2574
2575
            expr = delegate.markEnd(delegate.createConditionalExpression(expr, consequent, alternate));
2576
        } else {
2577
            delegate.markEnd({});
2578
        }
2579
2580
        return expr;
2581
    }
2582
2583
    // 11.13 Assignment Operators
2584
2585
    function parseAssignmentExpression() {
2586
        var token, left, right, node;
2587
2588
        token = lookahead;
2589
        delegate.markStart();
2590
        node = left = parseConditionalExpression();
2591
2592
        if (matchAssign()) {
2593
            // LeftHandSideExpression
2594
            if (!isLeftHandSide(left)) {
2595
                throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2596
            }
2597
2598
            // 11.13.1
2599
            if (strict && left.type === Syntax.Identifier && isRestrictedWord(left.name)) {
2600
                throwErrorTolerant(token, Messages.StrictLHSAssignment);
2601
            }
2602
2603
            token = lex();
2604
            right = parseAssignmentExpression();
2605
            node = delegate.createAssignmentExpression(token.value, left, right);
2606
        }
2607
2608
        return delegate.markEndIf(node);
2609
    }
2610
2611
    // 11.14 Comma Operator
2612
2613
    function parseExpression() {
2614
        var expr;
2615
2616
        delegate.markStart();
2617
        expr = parseAssignmentExpression();
2618
2619
        if (match(',')) {
2620
            expr = delegate.createSequenceExpression([ expr ]);
2621
2622
            while (index < length) {
2623
                if (!match(',')) {
2624
                    break;
2625
                }
2626
                lex();
2627
                expr.expressions.push(parseAssignmentExpression());
2628
            }
2629
        }
2630
2631
        return delegate.markEndIf(expr);
2632
    }
2633
2634
    // 12.1 Block
2635
2636
    function parseStatementList() {
2637
        var list = [],
2638
            statement;
2639
2640
        while (index < length) {
2641
            if (match('}')) {
2642
                break;
2643
            }
2644
            statement = parseSourceElement();
2645
            if (typeof statement === 'undefined') {
2646
                break;
2647
            }
2648
            list.push(statement);
2649
        }
2650
2651
        return list;
2652
    }
2653
2654
    function parseBlock() {
2655
        var block;
2656
2657
        skipComment();
2658
        delegate.markStart();
2659
        expect('{');
2660
2661
        block = parseStatementList();
2662
2663
        // mamacdon 853a9865
2664
        // @ 1.0.0 esprima.js:2204
2665
        //expect('}');
2666
        expectConditionCloseBracketWrapThrow();
2667
2668
        return delegate.markEnd(delegate.createBlockStatement(block));
2669
    }
2670
2671
    // 12.2 Variable Statement
2672
2673
    function parseVariableIdentifier() {
2674
        var token;
2675
2676
        skipComment();
2677
        delegate.markStart();
2678
        token = lex();
2679
2680
        if (token.type !== Token.Identifier) {
2681
            throwUnexpected(token);
2682
        }
2683
2684
        return delegate.markEnd(delegate.createIdentifier(token.value));
2685
    }
2686
2687
    function parseVariableDeclaration(kind) {
2688
        var init = null, id;
2689
2690
        skipComment();
2691
        delegate.markStart();
2692
        id = parseVariableIdentifier();
2693
2694
        // 12.2.1
2695
        if (strict && isRestrictedWord(id.name)) {
2696
            throwErrorTolerant({}, Messages.StrictVarName);
2697
        }
2698
2699
        if (kind === 'const') {
2700
            expect('=');
2701
            init = parseAssignmentExpression();
2702
        } else if (match('=')) {
2703
            lex();
2704
            init = parseAssignmentExpression();
2705
        }
2706
2707
        return delegate.markEnd(delegate.createVariableDeclarator(id, init));
2708
    }
2709
2710
    function parseVariableDeclarationList(kind) {
2711
        var list = [];
2712
2713
        do {
2714
            list.push(parseVariableDeclaration(kind));
2715
            if (!match(',')) {
2716
                break;
2717
            }
2718
            lex();
2719
        } while (index < length);
2720
2721
        return list;
2722
    }
2723
2724
    function parseVariableStatement() {
2725
        var declarations;
2726
2727
        expectKeyword('var');
2728
2729
        declarations = parseVariableDeclarationList();
2730
2731
        consumeSemicolon();
2732
2733
        return delegate.createVariableDeclaration(declarations, 'var');
2734
    }
2735
2736
    // kind may be `const` or `let`
2737
    // Both are experimental and not in the specification yet.
2738
    // see http://wiki.ecmascript.org/doku.php?id=harmony:const
2739
    // and http://wiki.ecmascript.org/doku.php?id=harmony:let
2740
    function parseConstLetDeclaration(kind) {
2741
        var declarations;
2742
2743
        skipComment();
2744
        delegate.markStart();
2745
2746
        expectKeyword(kind);
2747
2748
        declarations = parseVariableDeclarationList(kind);
2749
2750
        consumeSemicolon();
2751
2752
        return delegate.markEnd(delegate.createVariableDeclaration(declarations, kind));
2753
    }
2754
2755
    // 12.3 Empty Statement
2756
2757
    function parseEmptyStatement() {
2758
        expect(';');
2759
        return delegate.createEmptyStatement();
2760
    }
2761
2762
    // 12.4 Expression Statement
2763
2764
    function parseExpressionStatement() {
2765
        var expr = parseExpression();
2766
        consumeSemicolon();
2767
        return delegate.createExpressionStatement(expr);
2768
    }
2769
2770
    // 12.5 If statement
2771
2772
    function parseIfStatement() {
2773
    	
2774
        var test, consequent, alternate;
2775
2776
        expectKeyword('if');
2777
2778
        expect('(');
2779
2780
        test = parseExpression();
2781
2782
        // mamacdon 853a9865
2783
        //expect(')');
2784
        expectConditionCloseParenWrapThrow();
2785
2786
        consequent = parseStatement();
2787
        // mamacdon 853a9865: required because of the check in wrapTracking that returns nothing if node is undefined
2788
		// TODO: delegate handles tracking now, check if this test is still needed
2789
        if (!consequent) {
2790
            consequent = null;
2791
        }
2792
        if (matchKeyword('else')) {
2793
            lex();
2794
            alternate = parseStatement();
2795
        } else {
2796
            alternate = null;
2797
        }
2798
2799
        return delegate.createIfStatement(test, consequent, alternate);
2800
    }
2801
2802
    // 12.6 Iteration Statements
2803
2804
    function parseDoWhileStatement() {
2805
        var body, test, oldInIteration;
2806
2807
        expectKeyword('do');
2808
2809
        oldInIteration = state.inIteration;
2810
        state.inIteration = true;
2811
2812
        body = parseStatement();
2813
2814
        state.inIteration = oldInIteration;
2815
2816
        expectKeyword('while');
2817
2818
        expect('(');
2819
2820
        test = parseExpression();
2821
2822
        expect(')');
2823
2824
        if (match(';')) {
2825
            lex();
2826
        }
2827
2828
        return delegate.createDoWhileStatement(body, test);
2829
    }
2830
2831
    function parseWhileStatement() {
2832
        var test, body, oldInIteration;
2833
2834
        expectKeyword('while');
2835
2836
        expect('(');
2837
2838
        test = parseExpression();
2839
2840
        // mamacdon 853a9865
2841
        //expect(')');
2842
        expectConditionCloseParenWrapThrow();
2843
2844
        oldInIteration = state.inIteration;
2845
        state.inIteration = true;
2846
2847
        body = parseStatement();
2848
2849
        state.inIteration = oldInIteration;
2850
2851
        return delegate.createWhileStatement(test, body);
2852
    }
2853
2854
    function parseForVariableDeclaration() {
2855
        var token, declarations;
2856
2857
        delegate.markStart();
2858
        token = lex();
2859
        declarations = parseVariableDeclarationList();
2860
2861
        return delegate.markEnd(delegate.createVariableDeclaration(declarations, token.value));
2862
    }
2863
2864
    function parseForStatement() {
2865
        var init, test, update, left, right, body, oldInIteration;
2866
2867
        init = test = update = null;
2868
2869
        expectKeyword('for');
2870
2871
        expect('(');
2872
2873
        if (match(';')) {
2874
            lex();
2875
        } else {
2876
            if (matchKeyword('var') || matchKeyword('let')) {
2877
                state.allowIn = false;
2878
                init = parseForVariableDeclaration();
2879
                state.allowIn = true;
2880
2881
                if (init.declarations.length === 1 && matchKeyword('in')) {
2882
                    lex();
2883
                    left = init;
2884
                    right = parseExpression();
2885
                    init = null;
2886
                }
2887
            } else {
2888
                state.allowIn = false;
2889
                init = parseExpression();
2890
                state.allowIn = true;
2891
2892
                if (matchKeyword('in')) {
2893
                    // LeftHandSideExpression
2894
                    if (!isLeftHandSide(init)) {
2895
                        throwErrorTolerant({}, Messages.InvalidLHSInForIn);
2896
                    }
2897
2898
                    lex();
2899
                    left = init;
2900
                    right = parseExpression();
2901
                    init = null;
2902
                }
2903
            }
2904
2905
            if (typeof left === 'undefined') {
2906
                expect(';');
2907
            }
2908
        }
2909
2910
        if (typeof left === 'undefined') {
2911
2912
            if (!match(';')) {
2913
                test = parseExpression();
2914
            }
2915
            expect(';');
2916
2917
            if (!match(')')) {
2918
                update = parseExpression();
2919
            }
2920
        }
2921
2922
        // mamacdon 853a9865
2923
        //expect(')');
2924
        expectConditionCloseParenWrapThrow();
2925
2926
        oldInIteration = state.inIteration;
2927
        state.inIteration = true;
2928
2929
        body = parseStatement();
2930
2931
        state.inIteration = oldInIteration;
2932
2933
        return (typeof left === 'undefined') ?
2934
                delegate.createForStatement(init, test, update, body) :
2935
                delegate.createForInStatement(left, right, body);
2936
    }
2937
2938
    // 12.7 The continue statement
2939
2940
    function parseContinueStatement() {
2941
        var label = null, key;
2942
2943
        expectKeyword('continue');
2944
2945
        // Optimize the most common form: 'continue;'.
2946
        if (source.charCodeAt(index) === 59) {
2947
            lex();
2948
2949
            if (!state.inIteration) {
2950
                throwError({}, Messages.IllegalContinue);
2951
            }
2952
2953
            return delegate.createContinueStatement(null);
2954
        }
2955
2956
        if (peekLineTerminator()) {
2957
            if (!state.inIteration) {
2958
                throwError({}, Messages.IllegalContinue);
2959
            }
2960
2961
            return delegate.createContinueStatement(null);
2962
        }
2963
2964
        if (lookahead.type === Token.Identifier) {
2965
            label = parseVariableIdentifier();
2966
2967
            key = '$' + label.name;
2968
            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
2969
                throwError({}, Messages.UnknownLabel, label.name);
2970
            }
2971
        }
2972
2973
        consumeSemicolon();
2974
2975
        if (label === null && !state.inIteration) {
2976
            throwError({}, Messages.IllegalContinue);
2977
        }
2978
2979
        return delegate.createContinueStatement(label);
2980
    }
2981
2982
    // 12.8 The break statement
2983
2984
    function parseBreakStatement() {
2985
        var label = null, key;
2986
2987
        expectKeyword('break');
2988
2989
        // Catch the very common case first: immediately a semicolon (char #59).
2990
        if (source.charCodeAt(index) === 59) {
2991
            lex();
2992
2993
            if (!(state.inIteration || state.inSwitch)) {
2994
                throwError({}, Messages.IllegalBreak);
2995
            }
2996
2997
            return delegate.createBreakStatement(null);
2998
        }
2999
3000
        if (peekLineTerminator()) {
3001
            if (!(state.inIteration || state.inSwitch)) {
3002
                throwError({}, Messages.IllegalBreak);
3003
            }
3004
3005
            return delegate.createBreakStatement(null);
3006
        }
3007
3008
        if (lookahead.type === Token.Identifier) {
3009
            label = parseVariableIdentifier();
3010
3011
            key = '$' + label.name;
3012
            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
3013
                throwError({}, Messages.UnknownLabel, label.name);
3014
            }
3015
        }
3016
3017
        consumeSemicolon();
3018
3019
        if (label === null && !(state.inIteration || state.inSwitch)) {
3020
            throwError({}, Messages.IllegalBreak);
3021
        }
3022
3023
        return delegate.createBreakStatement(label);
3024
    }
3025
3026
    // 12.9 The return statement
3027
3028
    function parseReturnStatement() {
3029
        var argument = null;
3030
3031
        expectKeyword('return');
3032
3033
        if (!state.inFunctionBody) {
3034
            throwErrorTolerant({}, Messages.IllegalReturn);
3035
        }
3036
3037
        // 'return' followed by a space and an identifier is very common.
3038
        if (source.charCodeAt(index) === 32) {
3039
            if (isIdentifierStart(source.charCodeAt(index + 1))) {
3040
                argument = parseExpression();
3041
                consumeSemicolon();
3042
                return delegate.createReturnStatement(argument);
3043
            }
3044
        }
3045
3046
        if (peekLineTerminator()) {
3047
            return delegate.createReturnStatement(null);
3048
        }
3049
3050
        if (!match(';')) {
3051
            if (!match('}') && lookahead.type !== Token.EOF) {
3052
                argument = parseExpression();
3053
            }
3054
        }
3055
3056
        consumeSemicolon();
3057
3058
        return delegate.createReturnStatement(argument);
3059
    }
3060
3061
    // 12.10 The with statement
3062
3063
    function parseWithStatement() {
3064
        var object, body;
3065
3066
        if (strict) {
3067
            throwErrorTolerant({}, Messages.StrictModeWith);
3068
        }
3069
3070
        expectKeyword('with');
3071
3072
        expect('(');
3073
3074
        object = parseExpression();
3075
3076
        expect(')');
3077
3078
        body = parseStatement();
3079
3080
        return delegate.createWithStatement(object, body);
3081
    }
3082
3083
    // 12.10 The swith statement
3084
3085
    function parseSwitchCase() {
3086
        var test,
3087
            consequent = [],
3088
            statement;
3089
3090
        skipComment();
3091
        delegate.markStart();
3092
        if (matchKeyword('default')) {
3093
            lex();
3094
            test = null;
3095
        } else {
3096
            expectKeyword('case');
3097
            test = parseExpression();
3098
        }
3099
        expect(':');
3100
3101
        while (index < length) {
3102
            if (match('}') || matchKeyword('default') || matchKeyword('case')) {
3103
                break;
3104
            }
3105
            statement = parseStatement();
3106
            consequent.push(statement);
3107
        }
3108
3109
        return delegate.markEnd(delegate.createSwitchCase(test, consequent));
3110
    }
3111
3112
    function parseSwitchStatement() {
3113
        var discriminant, cases, clause, oldInSwitch, defaultFound;
3114
3115
        expectKeyword('switch');
3116
3117
        expect('(');
3118
3119
        discriminant = parseExpression();
3120
3121
        expect(')');
3122
3123
        expect('{');
3124
3125
        cases = [];
3126
3127
        if (match('}')) {
3128
            lex();
3129
            return delegate.createSwitchStatement(discriminant, cases);
3130
        }
3131
3132
        oldInSwitch = state.inSwitch;
3133
        state.inSwitch = true;
3134
        defaultFound = false;
3135
3136
        while (index < length) {
3137
            if (match('}')) {
3138
                break;
3139
            }
3140
            clause = parseSwitchCase();
3141
            if (clause.test === null) {
3142
                if (defaultFound) {
3143
                    throwError({}, Messages.MultipleDefaultsInSwitch);
3144
                }
3145
                defaultFound = true;
3146
            }
3147
            cases.push(clause);
3148
        }
3149
3150
        state.inSwitch = oldInSwitch;
3151
3152
        expect('}');
3153
3154
        return delegate.createSwitchStatement(discriminant, cases);
3155
    }
3156
3157
    // 12.13 The throw statement
3158
3159
    function parseThrowStatement() {
3160
        var argument;
3161
3162
        expectKeyword('throw');
3163
3164
        if (peekLineTerminator()) {
3165
            throwError({}, Messages.NewlineAfterThrow);
3166
        }
3167
3168
        argument = parseExpression();
3169
3170
        consumeSemicolon();
3171
3172
        return delegate.createThrowStatement(argument);
3173
    }
3174
3175
    // 12.14 The try statement
3176
3177
    function parseCatchClause() {
3178
        var param, body;
3179
3180
        skipComment();
3181
        delegate.markStart();
3182
        expectKeyword('catch');
3183
3184
        expect('(');
3185
        if (match(')')) {
3186
            throwUnexpected(lookahead);
3187
        }
3188
3189
        param = parseVariableIdentifier();
3190
        // 12.14.1
3191
        if (strict && isRestrictedWord(param.name)) {
3192
            throwErrorTolerant({}, Messages.StrictCatchVariable);
3193
        }
3194
3195
        expect(')');
3196
        body = parseBlock();
3197
        return delegate.markEnd(delegate.createCatchClause(param, body));
3198
    }
3199
3200
    function parseTryStatement() {
3201
        var block, handlers = [], finalizer = null;
3202
3203
        expectKeyword('try');
3204
3205
        block = parseBlock();
3206
3207
        if (matchKeyword('catch')) {
3208
            handlers.push(parseCatchClause());
3209
        }
3210
3211
        if (matchKeyword('finally')) {
3212
            lex();
3213
            finalizer = parseBlock();
3214
        }
3215
3216
        if (handlers.length === 0 && !finalizer) {
3217
            throwError({}, Messages.NoCatchOrFinally);
3218
        }
3219
3220
        return delegate.createTryStatement(block, [], handlers, finalizer);
3221
    }
3222
3223
    // 12.15 The debugger statement
3224
3225
    function parseDebuggerStatement() {
3226
        expectKeyword('debugger');
3227
3228
        consumeSemicolon();
3229
3230
        return delegate.createDebuggerStatement();
3231
    }
3232
3233
    // 12 Statements
3234
3235
    function parseStatement() {
3236
        var type = lookahead.type,
3237
            expr,
3238
            labeledBody,
3239
            key;
3240
3241
        if (type === Token.EOF) {
3242
            throwUnexpected(lookahead);
3243
        }
3244
3245
        skipComment();
3246
        delegate.markStart();
3247
3248
        if (type === Token.Punctuator) {
3249
            switch (lookahead.value) {
3250
            case ';':
3251
                return delegate.markEnd(parseEmptyStatement());
3252
            case '{':
3253
                return delegate.markEnd(parseBlock());
3254
            case '(':
3255
                return delegate.markEnd(parseExpressionStatement());
3256
            default:
3257
                break;
3258
            }
3259
        }
3260
3261
        if (type === Token.Keyword) {
3262
            switch (lookahead.value) {
3263
            case 'break':
3264
                return delegate.markEnd(parseBreakStatement());
3265
            case 'continue':
3266
                return delegate.markEnd(parseContinueStatement());
3267
            case 'debugger':
3268
                return delegate.markEnd(parseDebuggerStatement());
3269
            case 'do':
3270
                return delegate.markEnd(parseDoWhileStatement());
3271
            case 'for':
3272
                return delegate.markEnd(parseForStatement());
3273
            case 'function':
3274
                return delegate.markEnd(parseFunctionDeclaration());
3275
            case 'if':
3276
                return delegate.markEnd(parseIfStatement());
3277
            case 'return':
3278
                return delegate.markEnd(parseReturnStatement());
3279
            case 'switch':
3280
                return delegate.markEnd(parseSwitchStatement());
3281
            case 'throw':
3282
                return delegate.markEnd(parseThrowStatement());
3283
            case 'try':
3284
                return delegate.markEnd(parseTryStatement());
3285
            case 'var':
3286
                return delegate.markEnd(parseVariableStatement());
3287
            case 'while':
3288
                return delegate.markEnd(parseWhileStatement());
3289
            case 'with':
3290
                return delegate.markEnd(parseWithStatement());
3291
            default:
3292
                break;
3293
            }
3294
        }
3295
3296
        expr = parseExpression();
3297
3298
        // 12.12 Labelled Statements
3299
        if (expr && (expr.type === Syntax.Identifier) && match(':')) { // mamacdon 1420b19
3300
            lex();
3301
3302
            key = '$' + expr.name;
3303
            if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
3304
                throwError({}, Messages.Redeclaration, 'Label', expr.name);
3305
            }
3306
3307
            state.labelSet[key] = true;
3308
            labeledBody = parseStatement();
3309
            delete state.labelSet[key];
3310
            return delegate.markEnd(delegate.createLabeledStatement(expr, labeledBody));
3311
        }
3312
3313
        consumeSemicolon();
3314
3315
        return delegate.markEnd(delegate.createExpressionStatement(expr));
3316
    }
3317
3318
    // 13 Function Definition
3319
3320
    function parseFunctionSourceElements() {
3321
        var sourceElement, sourceElements = [], token, directive, firstRestricted,
3322
            oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody;
3323
3324
        skipComment();
3325
        delegate.markStart();
3326
        expect('{');
3327
3328
        while (index < length) {
3329
            if (lookahead.type !== Token.StringLiteral) {
3330
                break;
3331
            }
3332
            token = lookahead;
3333
3334
            sourceElement = parseSourceElement();
3335
            sourceElements.push(sourceElement);
3336
            if (sourceElement.expression.type !== Syntax.Literal) {
3337
                // this is not directive
3338
                break;
3339
            }
3340
            directive = source.slice(token.range[0] + 1, token.range[1] - 1);
3341
            if (directive === 'use strict') {
3342
                strict = true;
3343
                if (firstRestricted) {
3344
                    throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
3345
                }
3346
            } else {
3347
                if (!firstRestricted && token.octal) {
3348
                    firstRestricted = token;
3349
                }
3350
            }
3351
        }
3352
3353
        oldLabelSet = state.labelSet;
3354
        oldInIteration = state.inIteration;
3355
        oldInSwitch = state.inSwitch;
3356
        oldInFunctionBody = state.inFunctionBody;
3357
3358
        state.labelSet = {};
3359
        state.inIteration = false;
3360
        state.inSwitch = false;
3361
        state.inFunctionBody = true;
3362
3363
        while (index < length) {
3364
            if (match('}')) {
3365
                break;
3366
            }
3367
            sourceElement = parseSourceElement();
3368
            if (typeof sourceElement === 'undefined') {
3369
                break;
3370
            }
3371
            sourceElements.push(sourceElement);
3372
        }
3373
3374
        // mamacdon 853a986
3375
        //expect('}');
3376
        expectConditionCloseBracketWrapThrow();
3377
3378
        state.labelSet = oldLabelSet;
3379
        state.inIteration = oldInIteration;
3380
        state.inSwitch = oldInSwitch;
3381
        state.inFunctionBody = oldInFunctionBody;
3382
3383
        return delegate.markEnd(delegate.createBlockStatement(sourceElements));
3384
    }
3385
3386
    function parseParams(firstRestricted) {
3387
        var param, params = [], token, stricted, paramSet, key, message;
3388
        expect('(');
3389
3390
        if (!match(')')) {
3391
            paramSet = {};
3392
            while (index < length) {
3393
                token = lookahead;
3394
                param = parseVariableIdentifier();
3395
                key = '$' + token.value;
3396
                if (strict) {
3397
                    if (isRestrictedWord(token.value)) {
3398
                        stricted = token;
3399
                        message = Messages.StrictParamName;
3400
                    }
3401
                    if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
3402
                        stricted = token;
3403
                        message = Messages.StrictParamDupe;
3404
                    }
3405
                } else if (!firstRestricted) {
3406
                    if (isRestrictedWord(token.value)) {
3407
                        firstRestricted = token;
3408
                        message = Messages.StrictParamName;
3409
                    } else if (isStrictModeReservedWord(token.value)) {
3410
                        firstRestricted = token;
3411
                        message = Messages.StrictReservedWord;
3412
                    } else if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
3413
                        firstRestricted = token;
3414
                        message = Messages.StrictParamDupe;
3415
                    }
3416
                }
3417
                params.push(param);
3418
                paramSet[key] = true;
3419
                if (match(')')) {
3420
                    break;
3421
                }
3422
                expect(',');
3423
            }
3424
        }
3425
3426
        expect(')');
3427
3428
        return {
3429
            params: params,
3430
            stricted: stricted,
3431
            firstRestricted: firstRestricted,
3432
            message: message
3433
        };
3434
    }
3435
3436
    function parseFunctionDeclaration() {
3437
        var id, params = [], body, token, stricted, tmp, firstRestricted, message, previousStrict;
3438
3439
        skipComment();
3440
        delegate.markStart();
3441
3442
        expectKeyword('function');
3443
        token = lookahead;
3444
        id = parseVariableIdentifier();
3445
        if (strict) {
3446
            if (isRestrictedWord(token.value)) {
3447
                throwErrorTolerant(token, Messages.StrictFunctionName);
3448
            }
3449
        } else {
3450
            if (isRestrictedWord(token.value)) {
3451
                firstRestricted = token;
3452
                message = Messages.StrictFunctionName;
3453
            } else if (isStrictModeReservedWord(token.value)) {
3454
                firstRestricted = token;
3455
                message = Messages.StrictReservedWord;
3456
            }
3457
        }
3458
3459
        tmp = parseParams(firstRestricted);
3460
        params = tmp.params;
3461
        stricted = tmp.stricted;
3462
        firstRestricted = tmp.firstRestricted;
3463
        if (tmp.message) {
3464
            message = tmp.message;
3465
        }
3466
3467
        previousStrict = strict;
3468
        body = parseFunctionSourceElements();
3469
        if (strict && firstRestricted) {
3470
            throwError(firstRestricted, message);
3471
        }
3472
        if (strict && stricted) {
3473
            throwErrorTolerant(stricted, message);
3474
        }
3475
        strict = previousStrict;
3476
3477
        return delegate.markEnd(delegate.createFunctionDeclaration(id, params, [], body));
3478
    }
3479
3480
    function parseFunctionExpression() {
3481
        var token, id = null, stricted, firstRestricted, message, tmp, params = [], body, previousStrict;
3482
3483
        delegate.markStart();
3484
        expectKeyword('function');
3485
3486
        if (!match('(')) {
3487
            token = lookahead;
3488
            id = parseVariableIdentifier();
3489
            if (strict) {
3490
                if (isRestrictedWord(token.value)) {
3491
                    throwErrorTolerant(token, Messages.StrictFunctionName);
3492
                }
3493
            } else {
3494
                if (isRestrictedWord(token.value)) {
3495
                    firstRestricted = token;
3496
                    message = Messages.StrictFunctionName;
3497
                } else if (isStrictModeReservedWord(token.value)) {
3498
                    firstRestricted = token;
3499
                    message = Messages.StrictReservedWord;
3500
                }
3501
            }
3502
        }
3503
3504
        tmp = parseParams(firstRestricted);
3505
        params = tmp.params;
3506
        stricted = tmp.stricted;
3507
        firstRestricted = tmp.firstRestricted;
3508
        if (tmp.message) {
3509
            message = tmp.message;
3510
        }
3511
3512
        previousStrict = strict;
3513
        body = parseFunctionSourceElements();
3514
        if (strict && firstRestricted) {
3515
            throwError(firstRestricted, message);
3516
        }
3517
        if (strict && stricted) {
3518
            throwErrorTolerant(stricted, message);
3519
        }
3520
        strict = previousStrict;
3521
3522
        return delegate.markEnd(delegate.createFunctionExpression(id, params, [], body));
3523
    }
3524
3525
    // 14 Program
3526
3527
    function parseSourceElement() {
3528
        if (lookahead.type === Token.Keyword) {
3529
            switch (lookahead.value) {
3530
            case 'const':
3531
            case 'let':
3532
                return parseConstLetDeclaration(lookahead.value);
3533
            case 'function':
3534
                return parseFunctionDeclaration();
3535
            default:
3536
                return parseStatement();
3537
            }
3538
        }
3539
3540
        if (lookahead.type !== Token.EOF) {
3541
            return parseStatement();
3542
        }
3543
    }
3544
3545
    function parseSourceElements() {
3546
        var sourceElement, sourceElements = [], token, directive, firstRestricted;
3547
3548
        while (index < length) {
3549
            token = lookahead;
3550
            if (token.type !== Token.StringLiteral) {
3551
                break;
3552
            }
3553
3554
            sourceElement = parseSourceElement();
3555
            sourceElements.push(sourceElement);
3556
            if (sourceElement.expression.type !== Syntax.Literal) {
3557
                // this is not directive
3558
                break;
3559
            }
3560
            directive = source.slice(token.range[0] + 1, token.range[1] - 1);
3561
            if (directive === 'use strict') {
3562
                strict = true;
3563
                if (firstRestricted) {
3564
                    throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
3565
                }
3566
            } else {
3567
                if (!firstRestricted && token.octal) {
3568
                    firstRestricted = token;
3569
                }
3570
            }
3571
        }
3572
3573
        while (index < length) {
3574
            sourceElement = parseSourceElement();
3575
            if (typeof sourceElement === 'undefined') {
3576
                break;
3577
            }
3578
            sourceElements.push(sourceElement);
3579
        }
3580
        return sourceElements;
3581
    }
3582
3583
    function parseProgram() {
3584
        var body;
3585
3586
        skipComment();
3587
        delegate.markStart();
3588
        strict = false;
3589
        peek();
3590
        body = parseSourceElements();
3591
        return delegate.markEnd(delegate.createProgram(body));
3592
    }
3593
3594
    function attachComments() {
3595
        var i, attacher, comment, leading, trailing;
3596
3597
        for (i = 0; i < extra.pendingComments.length; ++i) {
3598
            attacher = extra.pendingComments[i];
3599
            comment = attacher.comment;
3600
            leading = attacher.leading;
3601
            if (leading) {
3602
                if (typeof leading.leadingComments === 'undefined') {
3603
                    leading.leadingComments = [];
3604
                }
3605
                leading.leadingComments.push(attacher.comment);
3606
            }
3607
            trailing = attacher.trailing;
3608
            if (trailing) {
3609
                if (typeof trailing.trailingComments === 'undefined') {
3610
                    trailing.trailingComments = [];
3611
                }
3612
                trailing.trailingComments.push(attacher.comment);
3613
            }
3614
        }
3615
        extra.pendingComments = [];
3616
    }
3617
3618
    function filterTokenLocation() {
3619
        var i, entry, token, tokens = [];
3620
3621
        for (i = 0; i < extra.tokens.length; ++i) {
3622
            entry = extra.tokens[i];
3623
            token = {
3624
                type: entry.type,
3625
                value: entry.value
3626
            };
3627
            if (extra.range) {
3628
                token.range = entry.range;
3629
            }
3630
            if (extra.loc) {
3631
                token.loc = entry.loc;
3632
            }
3633
            tokens.push(token);
3634
        }
3635
3636
        extra.tokens = tokens;
3637
    }
3638
3639
    function LocationMarker() {
3640
        this.marker = [index, lineNumber, index - lineStart, 0, 0, 0];
3641
    }
3642
3643
    LocationMarker.prototype = {
3644
        constructor: LocationMarker,
3645
3646
        end: function () {
3647
            this.marker[3] = index;
3648
            this.marker[4] = lineNumber;
3649
            this.marker[5] = index - lineStart;
3650
        },
3651
3652
        apply: function (node) {
3653
            if (extra.range) {
3654
                node.range = [this.marker[0], this.marker[3]];
3655
            }
3656
            if (extra.loc) {
3657
                node.loc = {
3658
                    start: {
3659
                        line: this.marker[1],
3660
                        column: this.marker[2]
3661
                    },
3662
                    end: {
3663
                        line: this.marker[4],
3664
                        column: this.marker[5]
3665
                    }
3666
                };
3667
                node = delegate.postProcess(node);
3668
            }
3669
            if (extra.attachComment) {
3670
                delegate.processComment(node);
3671
            }
3672
        }
3673
    };
3674
3675
    function createLocationMarker() {
3676
        if (!extra.loc && !extra.range) {
3677
            return null;
3678
        }
3679
3680
        skipComment();
3681
3682
        return new LocationMarker();
3683
    }
3684
3685
    function tokenize(code, options) {
3686
        var toString,
3687
            token,
3688
            tokens;
3689
3690
        toString = String;
3691
        if (typeof code !== 'string' && !(code instanceof String)) {
3692
            code = toString(code);
3693
        }
3694
3695
        delegate = SyntaxTreeDelegate;
3696
        source = code;
3697
        index = 0;
3698
        lineNumber = (source.length > 0) ? 1 : 0;
3699
        lineStart = 0;
3700
        length = source.length;
3701
        lookahead = null;
3702
        state = {
3703
            allowIn: true,
3704
            labelSet: {},
3705
            inFunctionBody: false,
3706
            inIteration: false,
3707
            inSwitch: false,
3708
            lastCommentStart: -1
3709
        };
3710
3711
        extra = {};
3712
3713
        // Options matching.
3714
        options = options || {};
3715
3716
        // Of course we collect tokens here.
3717
        options.tokens = true;
3718
        extra.tokens = [];
3719
        extra.tokenize = true;
3720
        // The following two fields are necessary to compute the Regex tokens.
3721
        extra.openParenToken = -1;
3722
        extra.openCurlyToken = -1;
3723
3724
        extra.range = (typeof options.range === 'boolean') && options.range;
3725
        extra.loc = (typeof options.loc === 'boolean') && options.loc;
3726
3727
        if (typeof options.comment === 'boolean' && options.comment) {
3728
            extra.comments = [];
3729
        }
3730
        if (typeof options.tolerant === 'boolean' && options.tolerant) {
3731
            extra.errors = [];
3732
        }
3733
3734
        if (length > 0) {
3735
            if (typeof source[0] === 'undefined') {
3736
                // Try first to convert to a string. This is good as fast path
3737
                // for old IE which understands string indexing for string
3738
                // literals only and not for string object.
3739
                if (code instanceof String) {
3740
                    source = code.valueOf();
3741
                }
3742
            }
3743
        }
3744
3745
        try {
3746
            peek();
3747
            if (lookahead.type === Token.EOF) {
3748
                return extra.tokens;
3749
            }
3750
3751
            token = lex();
3752
            while (lookahead.type !== Token.EOF) {
3753
                try {
3754
                    token = lex();
3755
                } catch (lexError) {
3756
                    token = lookahead;
3757
                    if (extra.errors) {
3758
                        extra.errors.push(lexError);
3759
                        // We have to break on the first error
3760
                        // to avoid infinite loops.
3761
                        break;
3762
                    } else {
3763
                        throw lexError;
3764
                    }
3765
                }
3766
            }
3767
3768
            filterTokenLocation();
3769
            tokens = extra.tokens;
3770
            if (typeof extra.comments !== 'undefined') {
3771
                tokens.comments = extra.comments;
3772
            }
3773
            if (typeof extra.errors !== 'undefined') {
3774
                tokens.errors = extra.errors;
3775
            }
3776
        } catch (e) {
3777
            throw e;
3778
        } finally {
3779
            extra = {};
3780
        }
3781
        return tokens;
3782
    }
3783
3784
    function parse(code, options) {
3785
        var program, toString;
3786
3787
        toString = String;
3788
        if (typeof code !== 'string' && !(code instanceof String)) {
3789
            code = toString(code);
3790
        }
3791
3792
        delegate = SyntaxTreeDelegate;
3793
        source = code;
3794
        index = 0;
3795
        lineNumber = (source.length > 0) ? 1 : 0;
3796
        lineStart = 0;
3797
        length = source.length;
3798
        lookahead = null;
3799
        state = {
3800
            allowIn: true,
3801
            labelSet: {},
3802
            inFunctionBody: false,
3803
            inIteration: false,
3804
            inSwitch: false,
3805
            lastCommentStart: -1,
3806
            markerStack: []
3807
        };
3808
3809
        extra = {};
3810
        if (typeof options !== 'undefined') {
3811
            extra.range = (typeof options.range === 'boolean') && options.range;
3812
            extra.loc = (typeof options.loc === 'boolean') && options.loc;
3813
            extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment;
3814
3815
            if (extra.loc && options.source !== null && options.source !== undefined) {
3816
                extra.source = toString(options.source);
3817
            }
3818
3819
            if (typeof options.tokens === 'boolean' && options.tokens) {
3820
                extra.tokens = [];
3821
            }
3822
            if (typeof options.comment === 'boolean' && options.comment) {
3823
                extra.comments = [];
3824
            }
3825
            if (typeof options.tolerant === 'boolean' && options.tolerant) {
3826
                extra.errors = [];
3827
3828
				// mamacdon patch
3829
				extra.parseStatement = parseStatement;
3830
				extra.parseExpression = parseExpression;
3831
				extra.parseNonComputedProperty = parseNonComputedProperty;
3832
				extra.consumeSemicolon = consumeSemicolon;
3833
3834
				parseStatement = wrapThrowParseStatement(parseStatement);       // Note special case
3835
				parseExpression = wrapThrow(parseExpression);
3836
				// this enables 'foo.<EOF>' to return something
3837
				parseNonComputedProperty = wrapThrow(parseNonComputedProperty);
3838
				consumeSemicolon = wrapThrow(consumeSemicolon);
3839
            }
3840
            if (extra.attachComment) {
3841
                extra.range = true;
3842
                extra.pendingComments = [];
3843
                extra.comments = [];
3844
            }
3845
        }
3846
3847
        if (length > 0) {
3848
            if (typeof source[0] === 'undefined') {
3849
                // Try first to convert to a string. This is good as fast path
3850
                // for old IE which understands string indexing for string
3851
                // literals only and not for string object.
3852
                if (code instanceof String) {
3853
                    source = code.valueOf();
3854
                }
3855
            }
3856
        }
3857
3858
        try {
3859
            program = parseProgram();
3860
            if (typeof extra.comments !== 'undefined') {
3861
                program.comments = extra.comments;
3862
            }
3863
            if (typeof extra.tokens !== 'undefined') {
3864
                filterTokenLocation();
3865
                program.tokens = extra.tokens;
3866
            }
3867
            if (typeof extra.errors !== 'undefined') {
3868
                program.errors = extra.errors;
3869
            }
3870
            if (extra.attachComment) {
3871
                attachComments();
3872
            }
3873
        } catch (e) {
3874
            throw e;
3875
        } finally {
3876
			// mamacdon unpatch
3877
			parseStatement = extra.parseStatement;
3878
			parseExpression = extra.parseExpression;
3879
			parseNonComputedProperty = extra.parseNonComputedProperty;
3880
			consumeSemicolon = extra.consumeSemicolon;
3881
3882
            extra = {};
3883
        }
3884
3885
        return program;
3886
    }
3887
3888
	/**
3889
	 * @name expectConditionCloseBracketWrapThrow
3890
	 * @description Gracefully handles a missing '}' if the mode is set to tolerant
3891
	 * @function
3892
	 * @private
3893
	 * @since 5.0
3894
	 */
3895
	function expectConditionCloseBracketWrapThrow() {
3896
		if (extra.errors) {
3897
			// continue parsing even with missing close
3898
			// brace.  This gives a better AST for the
3899
			// block, as information about
3900
			// the parsed statements remain
3901
			try {
3902
				expect('}');
3903
			} catch (e) {
3904
				pushError(e);
3905
	        }
3906
		} else {
3907
			expect('}');
3908
		}
3909
	}
3910
3911
	/**
3912
	 * @name expectConditionCloseParenWrapThrow
3913
	 * @description For statements like if, while, for, etc. check for the ')' on the condition. If
3914
	 * it is not present, catch the error, and backtrack if we see a '{' instead (to continue parsing the block)
3915
	 * @function
3916
	 * @private
3917
	 * @throws The original error from  trying to consume the ')' char if not in tolerant mode
3918
	 * @since 5.0
3919
	 */
3920
	function expectConditionCloseParenWrapThrow() {
3921
        // needs generalizing to a 'expect A but don't consume if you hit B or C'
3922
        try {
3923
            expect(')');
3924
        } catch (e) {
3925
            if (extra.errors) {
3926
	            pushError(e);
3927
	            // If a { was hit instead of a ) then don't consume it, let us assume a ')' was 
3928
	            // missed and the consequent block is OK
3929
	            if (source[e.index] === '{') {
3930
	              index=e.index;
3931
	              lookahead = null;
3932
	            // activating this block will mean the following statement is parsed as a consequent / body.
3933
	            // without it the statement is considered not at all part of the enclosing statement at all
3934
	            //} else {
3935
	            //  rewind();
3936
	            }
3937
            } else {
3938
                throw e;
3939
            }
3940
        }
3941
	}
3942
    // mamacdon 1420b19
3943
    // @ 1.0.0 esprima.js:1609
3944
	/**
3945
	 * @name pushError
3946
     * @description Add the error if not already reported.
3947
     * @function
3948
     * @private
3949
     * @param {Object} error The error object to push
3950
     * @since 5.0
3951
     */
3952
    function pushError(error) {
3953
        var len = extra.errors.length;
3954
        for (var e=0; e < len; e++) {
3955
            var existingError = extra.errors[e];
3956
            if (existingError.index === error.index && existingError.message === error.message) {
3957
                return; // do not add duplicate
3958
            }
3959
        }
3960
        extra.errors.push(error);
3961
    }
3962
    
3963
    //Recovery
3964
    function wrapThrow(parseFunction) {
3965
        return function () {
3966
            try {
3967
            	var initialHeight = state.markerStack.length;
3968
                return parseFunction.apply(null, arguments);
3969
            } catch (e) {
3970
				pushError(e);
3971
				// Clean up un-popped end markers from failed parse
3972
				while (state.markerStack.length > initialHeight)
3973
					delegate.markEndIf(null);
3974
				return null;
3975
            }
3976
        };
3977
    }
3978
    
3979
    function wrapThrowParseStatement(parseFunction) {
3980
        return function () {
3981
            extra.statementStart = index; // record where attempting to parse statement from
3982
            try {
3983
                return parseFunction.apply(null, arguments);
3984
            } catch (e) {
3985
				pushError(e);
3986
//				return null;   // why is this commented out
3987
            }
3988
        };
3989
    }
3990
3991
    /**
3992
     * @name isNewlineOrSemicolon
3993
     * @description If the given char is the new line char or a semicolon char
3994
     * @function
3995
     * @private
3996
     * @param {String} ch The character to check
3997
     * @returns {Boolean} <code>true</code> if the char is a new line or semicolon <code>false</code> otherwise
3998
     * @since 5.0
3999
     */
4000
    function isNewlineOrSemicolon(ch) {
4001
      return ch===';' || ch==='\n';
4002
    }
4003
    
4004
    /**
4005
     * @name rewind
4006
     * @descripton Rewind the lex position to the most recent newline or semicolon.  If that turns out
4007
     * to be the same position as the most recent parsing of a statement was attempted at, 
4008
     * don't rewind (because it will fail in the same way).  If it turns out to be the same
4009
     * position as where we last rewound to, don't do it.  Clears the buffer and sets the
4010
     * index in order to continue lexing from the new position.
4011
     * @function
4012
     * @private
4013
     * @since 5.0
4014
     */
4015
    function rewind() {
4016
        var idx = index;
4017
        while (idx>0 && !isNewlineOrSemicolon(source[idx])) {
4018
            idx--;
4019
        }
4020
        if (idx<=extra.statementStart) {
4021
            return;
4022
        }
4023
        var doRewind = false;
4024
        if (extra.lastRewindLocation) {
4025
            doRewind = true;
4026
        } else {
4027
            var v = extra.lastRewindLocation;
4028
            if (v!==idx) {
4029
              doRewind=true;
4030
            }
4031
        }	        
4032
        if (doRewind) {
4033
	        index = idx;
4034
	        peek(); // recalculate lookahead
4035
	        extra.lastRewindLocation = index;
4036
        }
4037
    }
4038
4039
    // mamacdon 1420b19
4040
    // @ 1.0.0 esprima.js:1661
4041
    // TODO refactor
4042
	/**
4043
	 * @name rewindToInterestingChar
4044
     * @description From a position 'idx' in the source this function moves back through the source until
4045
     * it finds a non-whitespace (including newlines) character.  It will jump over block comments.
4046
     * Returns an object with properties: index - the index it rewound to.  lineChange - boolean indicating
4047
     * if a line was crossed during rewind.
4048
     * @function
4049
     * @private
4050
     * @param {Number} idx The index to rewind to
4051
     * @returns {Object} Returns the object with the index and line change to rewind to
4052
     * @since 5.0
4053
     */
4054
    function rewindToInterestingChar(idx) {
4055
        var done = false;
4056
        var lineChange=false;
4057
        var ch;
4058
        while (!done) {
4059
          ch = source[idx];
4060
          if (ch==='/') {
4061
            // possibly rewind over a block comment
4062
            if (idx>2 && source[idx-1]==='*') {
4063
                // it is, let's reverse over it
4064
                idx = idx - 2;
4065
                var skippedComment = false;
4066
                while (!skippedComment) {
4067
                    ch = source[idx];
4068
                    if (ch === '*') {
4069
                        if (idx>0 && source[idx-1]==='/') {
4070
                            skippedComment=true;
4071
                        }
4072
                    } else if (ch==='\n') {
4073
                        lineChange=true;
4074
                    }
4075
                    if (idx === 0) {
4076
                        skippedComment = true; // error scenario, hit front of array before finding /*
4077
                    }
4078
                    idx--;                
4079
                }
4080
            } else {
4081
              done=true;
4082
            }
4083
          } else 
4084
          if (ch==='\n') {
4085
              lineChange=true;
4086
          } else if (!isWhiteSpace(ch)) {
4087
              done=true;
4088
          }
4089
          if (!done) {
4090
              idx--;
4091
          }
4092
        }
4093
        return {"index":idx,"lineChange":lineChange};
4094
    }
4095
    
4096
    /**
4097
     * @name attemptRecoveryNonComputedProperty
4098
     * @description When a problem occurs in parseNonComputedProperty, attempt to reposition 
4099
     * the lexer to continue processing.
4100
     * Example: '(foo.)' we will hit the ')' instead of discovering a property and consuming the ')'
4101
     * will cause the parse of the paretheses to fail, so 'unconsume' it.
4102
     * Basically rewind by one token if punctuation (type 7) is hit and the char before it was
4103
     * a dot.  This will enable the enclosing parse rule to consume the punctuation.
4104
     * @function
4105
     * @private
4106
     * @param {String} token The token to try and recover from
4107
     * @since 5.0
4108
     */
4109
    function attemptRecoveryNonComputedProperty(token) {
4110
        if (token.value && token.type===Token.Punctuator) {
4111
            var rewindInfo = rewindToInterestingChar(index-token.value.length-1);
4112
            var idx = rewindInfo.index;
4113
            var ch= source[idx];
4114
            // Check if worth rewinding
4115
            // Special case:
4116
            // "foo.\n(foo())\n" - don't really want that to parse as "foo(foo())"
4117
            if (ch==='.' && rewindInfo.lineChange && token.value==='(') {
4118
                // do not recover in this case
4119
            } else if (ch==='.') {
4120
	            index = idx+1;
4121
//                lookahead=null;
4122
                peek(); // recalculate lookahead
4123
            }
4124
        }
4125
    }
4126
4127
    // Sync with *.json manifests.
4128
    exports.version = '1.1.0-dev';
4129
4130
    exports.tokenize = tokenize;
4131
4132
    exports.parse = parse;
4133
4134
    // Deep copy.
4135
    exports.Syntax = (function () {
4136
        var name, types = {};
4137
4138
        if (typeof Object.create === 'function') {
4139
            types = Object.create(null);
4140
        }
4141
4142
        for (name in Syntax) {
4143
            if (Syntax.hasOwnProperty(name)) {
4144
                types[name] = Syntax[name];
4145
            }
4146
        }
4147
4148
        if (typeof Object.freeze === 'function') {
4149
            Object.freeze(types);
4150
        }
4151
4152
        return types;
4153
    }());
4154
4155
}));
4156
/* vim: set sw=4 ts=4 et tw=80 : */
(-)a/bundles/org.eclipse.orion.client.javascript/web/javascript/astManager.js (-4 / +4 lines)
Lines 9-21 Link Here
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
/*global define esprima*/
12
/*global define */
13
define([
13
define([
14
	'orion/Deferred',
14
	'orion/Deferred',
15
	'orion/objects',
15
	'orion/objects',
16
	'orion/serialize',
16
	'orion/serialize',
17
	'esprima' //must stay at the end, does not export AMD module
17
	'esprima'
18
], function(Deferred, Objects, Serialize) {
18
], function(Deferred, Objects, Serialize, Esprima) {
19
	/**
19
	/**
20
	 * @description Object of error types
20
	 * @description Object of error types
21
	 * @since 5.0
21
	 * @since 5.0
Lines 63-69 Link Here
63
		 */
63
		 */
64
		parse: function(text) {
64
		parse: function(text) {
65
			try {
65
			try {
66
				var ast = esprima.parse(text, {
66
				var ast = Esprima.parse(text, {
67
					range: true,
67
					range: true,
68
					tolerant: true,
68
					tolerant: true,
69
					comment: true,
69
					comment: true,
(-)a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/astManagerTests.js (-1 lines)
Lines 102-108 Link Here
102
		    editorContext = result.editorContext,
102
		    editorContext = result.editorContext,
103
		    mockEsprima = result.mockEsprima;
103
		    mockEsprima = result.mockEsprima;
104
104
105
		var d = new Deferred();
106
		return withMockEsprima(mockEsprima, function() {
105
		return withMockEsprima(mockEsprima, function() {
107
			var i = 0;
106
			var i = 0;
108
			mockEsprima.parse = function() {
107
			mockEsprima.parse = function() {
(-)a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/demo.html (-72 lines)
Lines 1-72 Link Here
1
<!DOCTYPE html>
2
<html>
3
<head>
4
	<script src="../../../requirejs/require.js"></script>
5
	<script>
6
		var useNewEsprima = window.location.hash === "#new";
7
8
		/*jslint amd:true browser:true*/
9
		require({
10
			baseUrl: "../../",
11
			paths: {
12
				text: "requirejs/text",
13
				i18n: "requirejs/i18n",
14
				domReady: "requirejs/domReady",
15
				esprima: (useNewEsprima ? 'esprima/esprima_tolerant' : 'esprima/esprima'),
16
				estraverse: "estraverse/estraverse"
17
			}
18
		});
19
20
		require(["estraverse", "esprima", "domReady!"], function(Estraverse, _esprima) {
21
			var esprima = typeof window.esprima !== "undefined" ? window.esprima : _esprima;
22
23
			var element = document.getElementById("source");
24
			element.onchange = function() {
25
				var source = element.value.replace(/\\n/g, "\n");
26
				document.getElementById("source2").value = source;
27
				
28
				var ast = esprima.parse(source, {comment:true, tokens:true, tolerant:true, range:true, raw:true});
29
				var expected = [];
30
				Estraverse.traverse(ast, {
31
					enter: function(node) {
32
						var n = {};
33
						n.type = node.type;
34
						if (node.name)
35
							n.name = node.name;
36
						if (node.kind)
37
							n.kind = node.kind;
38
						if (node.range)
39
							n.range = node.range;
40
						if (node.value)
41
							n.value = node.value;
42
						expected.push(n);
43
					}
44
				});
45
				var result = {
46
					nodes: expected.slice(1) // omit Program
47
				};
48
				document.getElementById("testData").textContent = JSON.stringify(result.nodes)
49
					.replace(/"(\w+)":/g, function(match, propName) {
50
						return propName + ":";
51
					});
52
53
				document.getElementById("ast").value = JSON.stringify(ast);
54
			};
55
		});
56
		
57
	</script>
58
</head>
59
<form>
60
	<p>Source code</p>
61
	<textarea id="source" rows=20 cols=100></textarea>
62
63
	<p>Normalized</p>
64
	<textarea id="source2" readonly rows=5, cols=100></textarea>
65
66
	<p>Test data</p>
67
	<textarea id="testData" rows=10 cols=150></textarea>
68
69
	<p>AST</p>
70
	<textarea id="ast" rows=30 cols=100></textarea>
71
</form>
72
</html>
(-)a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/esprimaTolerantTests.html (-1 / +1 lines)
Lines 28-34 Link Here
28
<body>
28
<body>
29
	<h2>Esprima Tolerant Tests</h2>
29
	<h2>Esprima Tolerant Tests</h2>
30
	<p>
30
	<p>
31
		This suite tests the tolerant (recoverable) esprima parser
31
		This suite tests the tolerant (recoverable) Esprima parser
32
	</p>
32
	</p>
33
</body>
33
</body>
34
</html>
34
</html>
(-)a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/esprimaTolerantTests.js (-86 / +2829 lines)
Lines 1-5 Link Here
1
/*jslint amd:true*/
1
/*jslint amd:true*/
2
/*global esprima:true*/
2
/*global esprima:true console */
3
define([
3
define([
4
	"chai/chai",
4
	"chai/chai",
5
	"esprima",
5
	"esprima",
Lines 21-29 Link Here
21
			tolerant: true,
21
			tolerant: true,
22
			comment: true,
22
			comment: true,
23
			tokens: true,
23
			tokens: true,
24
			raw: true
24
			raw: true,
25
			attachComments:true
25
		});
26
		});
26
	}
27
	}
28
	/**
29
	 * @description Write out the 'nodes', 'tokens' annd 'errors' arrays for a given AST.
30
	 * Add this code to the AST managers' getAST() function to produce the test data from a target workspace
31
	 * @param {Object} ast The AST
32
	 */
33
	function writeTestData(ast) {
34
		var i = 0;
35
		console.log('--- TEST OUTPUT ---');
36
		var expected = [];
37
		Estraverse.traverse(ast, {
38
			enter: function(node) {
39
				if(node.type === 'Program') {
40
					return;
41
				}
42
				var n = {};
43
				n.type = node.type;
44
				if (node.name) {
45
					n.name = node.name;
46
				}
47
				if (node.kind) {
48
					n.kind = node.kind;
49
				}
50
				if (node.range) {
51
					n.range = node.range;
52
				}
53
				if (node.value && typeof node.value !== 'object') {
54
					n.value = node.value;
55
				}
56
				expected.push(n);
57
			}
58
		});
59
		var s = 'nodes: [';
60
		for(i = 0; i < expected.length; i++) {
61
			s += JSON.stringify(expected[i]);
62
			if(i < expected.length-1) {
63
				s += ',\n\t\t';
64
			}
65
		}
66
		s += '],\ntokens: [';
67
		expected = [];
68
		for(i = 0; i < ast.tokens.length; i++) {
69
			var n = {};
70
			var token = ast.tokens[i];
71
			n.type = token.type;
72
			n.range = token.range;
73
			n.value = token.value;
74
			expected.push(n);
75
		}
76
		for(i = 0; i < expected.length; i++) {
77
			s += JSON.stringify(expected[i]);
78
			if(i < expected.length-1) {
79
				s += ',\n\t\t';
80
			}
81
		}
82
		s += '],\nerrors: [';
83
		expected = [];
84
		for(i = 0; i < ast.errors.length; i++) {
85
			var error = ast.errors[i];
86
			expected.push({
87
				lineNumber : error.lineNumber,
88
				index : error.index,
89
				message : error.message,
90
				token : error.token
91
			});
92
		}
93
		for(i = 0; i < expected.length; i++) {
94
			s += JSON.stringify(expected[i]);
95
			if(i < expected.length-1) {
96
				s += ',\n\t\t';
97
			}
98
		}
99
		s += ']';
100
		console.log(s);
101
	}
102
	
27
	/* */
103
	/* */
28
	function pf(str /*, args*/) {
104
	function pf(str /*, args*/) {
29
		var args = Array.prototype.slice.call(arguments, 1);
105
		var args = Array.prototype.slice.call(arguments, 1);
Lines 37-42 Link Here
37
	 * @description Run a test
113
	 * @description Run a test
38
	 */
114
	 */
39
	function runTest(name, data) {
115
	function runTest(name, data) {
116
		assert(name !== null, "Each test must have a name");
40
		assert.ok(data.source);
117
		assert.ok(data.source);
41
		var ast = parseFull(data.source);
118
		var ast = parseFull(data.source);
42
119
Lines 62-70 Link Here
62
						assert(counter < expectedNodes.length, 'There are more nodes to visit: '+ JSON.stringify(node));
139
						assert(counter < expectedNodes.length, 'There are more nodes to visit: '+ JSON.stringify(node));
63
						var expected = expectedNodes[counter];
140
						var expected = expectedNodes[counter];
64
						assert.equal(node.type, expected.type, 'The node types differ');
141
						assert.equal(node.type, expected.type, 'The node types differ');
65
						assert(expected.range, 'The expected node has no range');
142
						assert(expected.range, 'The expected '+node.type+' node has no range');
66
						assert.equal(node.range[0], expected.range[0], 'The node starts differ');
143
						assert.equal(node.range[0], expected.range[0], 'The '+node.type+' node starts differ');
67
						assert.equal(node.range[1], expected.range[1], 'The node ends differ');
144
						assert.equal(node.range[1], expected.range[1], 'The '+node.type+' node ends differ');
68
						if (expected.name) {
145
						if (expected.name) {
69
							assert.equal(node.name, expected.name, 'The names differ');
146
							assert.equal(node.name, expected.name, 'The names differ');
70
						}
147
						}
Lines 85-91 Link Here
85
		var expectedErrors = data.errors, actualErrors = ast.errors;
162
		var expectedErrors = data.errors, actualErrors = ast.errors;
86
		if (expectedErrors) {
163
		if (expectedErrors) {
87
			expectedErrors = Array.isArray(expectedErrors) ? expectedErrors : [expectedErrors];
164
			expectedErrors = Array.isArray(expectedErrors) ? expectedErrors : [expectedErrors];
88
			assert.equal(actualErrors.length, expectedErrors.length, "Correct number of errors");
165
			assert.equal(actualErrors.length, expectedErrors.length, "Incorrect number of errors");
89
			expectedErrors.forEach(function(expected, i) {
166
			expectedErrors.forEach(function(expected, i) {
90
				var actual = actualErrors[i];
167
				var actual = actualErrors[i];
91
				var formatStr = "Error #%s has correct %s";
168
				var formatStr = "Error #%s has correct %s";
Lines 96-104 Link Here
96
					assert.equal(actual.index, expected.index, pf(formatStr, i, "index"));
173
					assert.equal(actual.index, expected.index, pf(formatStr, i, "index"));
97
				}
174
				}
98
				if (typeof expected.lineNumber === "number") {
175
				if (typeof expected.lineNumber === "number") {
99
					assert.equal(actual.lineNumber, expected.lineNumber, pf("Error %s has correct %s", i, "lineNumber"));
176
					assert.equal(actual.lineNumber, expected.lineNumber, pf("Error %s has incorrect %s", i, "lineNumber"));
100
				}
177
				}
101
				assert.equal(actual.message.replace(/^Line [0-9]*: /, ""), expected.message, pf("Error %s has correct %s", i, "message"));
178
				assert.equal(actual.message.replace(/^Line [0-9]*: /, ""), expected.message, pf("Error %s has incorrect %s", i, "message"));
102
			});
179
			});
103
		}
180
		}
104
181
Lines 263-361 Link Here
263
		/**
340
		/**
264
		 *
341
		 *
265
		 * Object property recovery tests
342
		 * Object property recovery tests
266
		 *
343
		 * @since 6.0
267
		 */
344
		 */
268
		"obj prop recovery1": {
345
		"obj prop ident recovery - ident only": {
269
			source: "var f = {\na\n};",
346
			source: "var f = {\na\n};",
270
			errors: [],
347
			errors: [{ index: 10, lineNumber: 2, message: "Unexpected token a" }],
271
			nodes: [{type:'VariableDelcaration', value:'f', range:[0, 14]}, {type:'VariableDeclarator'}, {type:'ObjectExpression', range:[8, 14]}],
348
			nodes: [{type:'VariableDeclaration', id:'f', range:[4, 14]}, 
272
			tokens: [{type:'Keyword', value:'var'}, {type:'Identifier', value:'f'}, {type:'Operand', value:'='}, {type:'Punctuator', value:'{'}, {type:'Identifier', value:'a'}, {type:'Punctuator', value:'}'}, {type:'Punctuator', value:';'}]
349
					{type:'VariableDeclarator', range: [7, 13]}, 
350
					{type:'Identifier', range: [4, 5]},
351
					{type:'ObjectExpression', range:[10, 13]}],
352
			tokens: [{type:'Keyword', value:'var', range: [0, 3]}, 
353
						{type:'Identifier', value:'f', range: [4, 5]}, 
354
						{type:'Punctuator', value:'=', range: [6, 7]}, 
355
						{type:'Punctuator', value:'{', range: [8, 9]}, 
356
						{type:'Identifier', value:'a', range: [12, 13]}, 
357
						{type:'Punctuator', value:'}', range: [13, 14]},
358
						{type:'Punctuator', value:';', range: [14, 15]}]
273
		},
359
		},
274
		"obj prop recovery2": {
360
		
275
			source: "var f = {\na:\n};",
361
		"obj prop ident recovery - ident only with postamble": {
276
			errors: [],
277
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property*/]
278
		},
279
		"obj prop recovery3": {
280
			source: "var f = {\na: b.\n};",
281
			errors: [],
282
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property*/]
283
		},
284
		"obj prop recovery4": {
285
			source: "var f = {\na: b/**/\n};",
286
			errors: [],
287
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property*/]
288
		},
289
		"obj prop recovery5": {
290
			source: "var f = {\na: b/**/\n};",
291
			errors: [],
292
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property*/]
293
		},
294
		"obj prop recovery6": {
295
			source: "var f = {\na.\n};",
296
			errors: [],
297
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression*/]
298
		},
299
		"obj prop recovery7": {
300
			source: "var f = {\na/**/\n};",
362
			source: "var f = {\na/**/\n};",
301
			errors: [],
363
			errors: [{ index: 10, lineNumber: 2, message: "Unexpected token a" }],
302
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression*/]
364
			nodes: [{type:'VariableDeclaration', id:'f', range:[4, 18]}, 
365
					{type:'VariableDeclarator', range: [7, 17]}, 
366
					{type:'Identifier', range: [4, 5]},
367
					{type:'ObjectExpression', range:[10, 17]}],
368
			tokens: [{type:'Keyword', value:'var', range: [0, 3]}, 
369
						{type:'Identifier', value:'f', range: [4, 5]}, 
370
						{type:'Punctuator', value:'=', range: [6, 7]}, 
371
						{type:'Punctuator', value:'{', range: [8, 9]}, 
372
						{type:'Identifier', value:'a', range: [12, 13]}, 
373
						{type:'Punctuator', value:'}', range: [19, 20]},
374
						{type:'Punctuator', value:';', range: [20, 21]}]
303
		},
375
		},
304
		"obj prop recovery8": {
376
		
305
			source: "var f = {\nz: function(){}\na: this.z\n};",
377
		"nested obj prop ident recovery - nested ident only": {
306
			errors: [],
378
			source: "var f = {one: {a}};",
307
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property*/]
379
			errors: [{ index: 15, lineNumber: 1, message: "Unexpected token a" }],
380
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,19]},
381
					{"type":"VariableDeclarator","range":[7,18]},
382
					{"type":"Identifier","name":"f","range":[4,5]},
383
					{"type":"ObjectExpression","range":[9,18]},
384
					{"type":"Property","kind":"init","range":[13,17]},
385
					{"type":"Identifier","name":"one","range":[9,12]},
386
					{"type":"ObjectExpression","range":[15,17]}],
387
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
388
					{"type":"Identifier","range":[4,5],"value":"f"},
389
					{"type":"Punctuator","range":[6,7],"value":"="},
390
					{"type":"Punctuator","range":[8,9],"value":"{"},
391
					{"type":"Identifier","range":[9,12],"value":"one"},
392
					{"type":"Punctuator","range":[12,13],"value":":"},
393
					{"type":"Punctuator","range":[14,15],"value":"{"},
394
					{"type":"Identifier","range":[15,16],"value":"a"},
395
					{"type":"Punctuator","range":[16,17],"value":"}"},
396
					{"type":"Punctuator","range":[17,18],"value":"}"},
397
					{"type":"Punctuator","range":[18,19],"value":";"}]
308
		},
398
		},
309
		"obj prop recovery9": {
399
		
310
			source: "var f = {\nz: function(){}\na: this.z(\n};",
400
		"obj prop ident recovery - successive 1": {
311
			errors: [],
401
			source: "var f = {a b:1};",
312
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property*/]
402
			errors: [{ index: 9, lineNumber: 1, message: "Unexpected token a" }],
403
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,16]},
404
					{"type":"VariableDeclarator","range":[7,15]},
405
					{"type":"Identifier","name":"f","range":[4,5]},
406
					{"type":"ObjectExpression","range":[9,15]},
407
					{"type":"Property","kind":"init","range":[12,14]},
408
					{"type":"Identifier","name":"b","range":[12,12]},
409
					{"type":"Literal","range":[13,14],"value":1}],
410
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
411
					{"type":"Identifier","range":[4,5],"value":"f"},
412
					{"type":"Punctuator","range":[6,7],"value":"="},
413
					{"type":"Punctuator","range":[8,9],"value":"{"},
414
					{"type":"Identifier","range":[9,10],"value":"a"},
415
					{"type":"Identifier","range":[11,12],"value":"b"},
416
					{"type":"Punctuator","range":[12,13],"value":":"},
417
					{"type":"Numeric","range":[13,14],"value":"1"},
418
					{"type":"Punctuator","range":[14,15],"value":"}"},
419
					{"type":"Punctuator","range":[15,16],"value":";"}]
313
		},
420
		},
314
		"obj prop recovery10": {
421
		
315
			source: "var f = {\nz: function(){}\na: this.z(this.)\n};",
422
		"obj prop ident recovery - successive 2": {
316
			errors: [],
423
			source: "var f = {a b:1,c:2};",
317
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property*/]
424
			errors: [{ index: 9, lineNumber: 1, message: "Unexpected token a" }],
425
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,20]},
426
					{"type":"VariableDeclarator","range":[7,19]},
427
					{"type":"Identifier","name":"f","range":[4,5]},
428
					{"type":"ObjectExpression","range":[9,19]},
429
					{"type":"Property","kind":"init","range":[12,14]},
430
					{"type":"Identifier","name":"b","range":[12,12]},
431
					{"type":"Literal","range":[13,14],"value":1},
432
					{"type":"Property","kind":"init","range":[15,18]},
433
					{"type":"Identifier","name":"c","range":[15,16]},
434
					{"type":"Literal","range":[17,18],"value":2}],
435
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
436
					{"type":"Identifier","range":[4,5],"value":"f"},
437
					{"type":"Punctuator","range":[6,7],"value":"="},
438
					{"type":"Punctuator","range":[8,9],"value":"{"},
439
					{"type":"Identifier","range":[9,10],"value":"a"},
440
					{"type":"Identifier","range":[11,12],"value":"b"},
441
					{"type":"Punctuator","range":[12,13],"value":":"},
442
					{"type":"Numeric","range":[13,14],"value":"1"},
443
					{"type":"Punctuator","range":[14,15],"value":","},
444
					{"type":"Identifier","range":[15,16],"value":"c"},
445
					{"type":"Punctuator","range":[16,17],"value":":"},
446
					{"type":"Numeric","range":[17,18],"value":"2"},
447
					{"type":"Punctuator","range":[18,19],"value":"}"},
448
					{"type":"Punctuator","range":[19,20],"value":";"}]
318
		},
449
		},
319
		"obj prop recovery11": {
450
		
320
			source: "var f = {\na: {\n};",
451
		"obj prop ident recovery - successive 3": {
321
			errors: [],
452
			source: "var f = {b:1,a};",
322
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property*/]
453
			errors: [{ index: 13, lineNumber: 1, message: "Unexpected token a" }],
454
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,16]},
455
					{"type":"VariableDeclarator","range":[7,15]},
456
					{"type":"Identifier","name":"f","range":[4,5]},
457
					{"type":"ObjectExpression","range":[13,15]},
458
					{"type":"Property","kind":"init","range":[9,12]},
459
					{"type":"Identifier","name":"b","range":[9,10]},
460
					{"type":"Literal","range":[11,12],"value":1}],
461
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
462
					{"type":"Identifier","range":[4,5],"value":"f"},
463
					{"type":"Punctuator","range":[6,7],"value":"="},
464
					{"type":"Punctuator","range":[8,9],"value":"{"},
465
					{"type":"Identifier","range":[9,10],"value":"b"},
466
					{"type":"Punctuator","range":[10,11],"value":":"},
467
					{"type":"Numeric","range":[11,12],"value":"1"},
468
					{"type":"Punctuator","range":[12,13],"value":","},
469
					{"type":"Identifier","range":[13,14],"value":"a"},
470
					{"type":"Punctuator","range":[14,15],"value":"}"},
471
					{"type":"Punctuator","range":[15,16],"value":";"}]
323
		},
472
		},
324
		"nested obj prop recovery1": {
473
		
325
			source: "var f = {\none: {\na}\n};",
474
		"obj prop ident recovery - successive 4": {
326
			errors: [],
475
			source: "var f = {b:1,c:2,a};",
327
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property -> ObjectExpression*/]
476
			errors: [{ index: 17, lineNumber: 1, message: "Unexpected token a" }],
477
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,20]},
478
					{"type":"VariableDeclarator","range":[7,19]},
479
					{"type":"Identifier","name":"f","range":[4,5]},
480
					{"type":"ObjectExpression","range":[17,19]},
481
					{"type":"Property","kind":"init","range":[9,12]},
482
					{"type":"Identifier","name":"b","range":[9,10]},
483
					{"type":"Literal","range":[11,12],"value":1},
484
					{"type":"Property","kind":"init","range":[13,16]},
485
					{"type":"Identifier","name":"c","range":[13,14]},
486
					{"type":"Literal","range":[15,16],"value":2}],
487
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
488
					{"type":"Identifier","range":[4,5],"value":"f"},
489
					{"type":"Punctuator","range":[6,7],"value":"="},
490
					{"type":"Punctuator","range":[8,9],"value":"{"},
491
					{"type":"Identifier","range":[9,10],"value":"b"},
492
					{"type":"Punctuator","range":[10,11],"value":":"},
493
					{"type":"Numeric","range":[11,12],"value":"1"},
494
					{"type":"Punctuator","range":[12,13],"value":","},
495
					{"type":"Identifier","range":[13,14],"value":"c"},
496
					{"type":"Punctuator","range":[14,15],"value":":"},
497
					{"type":"Numeric","range":[15,16],"value":"2"},
498
					{"type":"Punctuator","range":[16,17],"value":","},
499
					{"type":"Identifier","range":[17,18],"value":"a"},
500
					{"type":"Punctuator","range":[18,19],"value":"}"},
501
					{"type":"Punctuator","range":[19,20],"value":";"}]
328
		},
502
		},
329
		"nested obj prop recovery2": {
503
		
330
			source: "var f = {\none: {\na:}\n};",
504
		"obj prop ident recovery - successive 5": {
331
			errors: [],
505
			source: "var f = {b:1,a c:2};",
332
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property -> ObjectExpression -> Property*/]
506
			errors: [{ index: 13, lineNumber: 1, message: "Unexpected token a" }],
507
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,20]},
508
					{"type":"VariableDeclarator","range":[7,19]},
509
					{"type":"Identifier","name":"f","range":[4,5]},
510
					{"type":"ObjectExpression","range":[13,19]},
511
					{"type":"Property","kind":"init","range":[9,12]},
512
					{"type":"Identifier","name":"b","range":[9,10]},
513
					{"type":"Literal","range":[11,12],"value":1},
514
					{"type":"Property","kind":"init","range":[16,18]},
515
					{"type":"Identifier","name":"c","range":[16,16]},
516
					{"type":"Literal","range":[17,18],"value":2}],
517
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
518
					{"type":"Identifier","range":[4,5],"value":"f"},
519
					{"type":"Punctuator","range":[6,7],"value":"="},
520
					{"type":"Punctuator","range":[8,9],"value":"{"},
521
					{"type":"Identifier","range":[9,10],"value":"b"},
522
					{"type":"Punctuator","range":[10,11],"value":":"},
523
					{"type":"Numeric","range":[11,12],"value":"1"},
524
					{"type":"Punctuator","range":[12,13],"value":","},
525
					{"type":"Identifier","range":[13,14],"value":"a"},
526
					{"type":"Identifier","range":[15,16],"value":"c"},
527
					{"type":"Punctuator","range":[16,17],"value":":"},
528
					{"type":"Numeric","range":[17,18],"value":"2"},
529
					{"type":"Punctuator","range":[18,19],"value":"}"},
530
					{"type":"Punctuator","range":[19,20],"value":";"}]
333
		},
531
		},
334
		"nested obj prop recovery3": {
532
		
335
			source: "var f = {\none: {\na: d}\n};",
533
		'obj prop ident recovery - successive 6': {
336
			errors: [],
534
			source: 'var f = {one: {a b:1,c}};',
337
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property -> ObjectExpression -> Property*/]
535
			errors: [{"lineNumber":1,"index":15,"message":"Unexpected token a","token":"a"},
536
					{"lineNumber":1,"index":21,"message":"Unexpected token c","token":"c"}],
537
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,25]},
538
					{"type":"VariableDeclarator","range":[7,24]},
539
					{"type":"Identifier","name":"f","range":[4,5]},
540
					{"type":"ObjectExpression","range":[13,24]},
541
					{"type":"Property","kind":"init","range":[13,23]},
542
					{"type":"Identifier","name":"one","range":[9,12]},
543
					{"type":"ObjectExpression","range":[21,23]},
544
					{"type":"Property","kind":"init","range":[18,20]},
545
					{"type":"Identifier","name":"b","range":[18,18]},
546
					{"type":"Literal","range":[19,20],"value":1}],
547
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
548
					{"type":"Identifier","range":[4,5],"value":"f"},
549
					{"type":"Punctuator","range":[6,7],"value":"="},
550
					{"type":"Punctuator","range":[8,9],"value":"{"},
551
					{"type":"Identifier","range":[9,12],"value":"one"},
552
					{"type":"Punctuator","range":[12,13],"value":":"},
553
					{"type":"Punctuator","range":[14,15],"value":"{"},
554
					{"type":"Identifier","range":[15,16],"value":"a"},
555
					{"type":"Identifier","range":[17,18],"value":"b"},
556
					{"type":"Punctuator","range":[18,19],"value":":"},
557
					{"type":"Numeric","range":[19,20],"value":"1"},
558
					{"type":"Punctuator","range":[20,21],"value":","},
559
					{"type":"Identifier","range":[21,22],"value":"c"},
560
					{"type":"Punctuator","range":[22,23],"value":"}"},
561
					{"type":"Punctuator","range":[23,24],"value":"}"},
562
					{"type":"Punctuator","range":[24,25],"value":";"}]
338
		},
563
		},
339
		"nested obj prop recovery4": {
564
		
340
			source: "var f = {\none: {\na: d.}\n};",
565
		'obj prop ident recovery - successive 7': {
341
			errors: [],
566
			source: 'var f = {one: {a c b:1}};',
342
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property -> ObjectExpression -> Property*/]
567
			errors: [{"lineNumber":1,"index":15,"message":"Unexpected token a","token":"a"},
568
					{"lineNumber":1,"index":17,"message":"Unexpected token c","token":"c"}],
569
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,25]},
570
					{"type":"VariableDeclarator","range":[7,24]},
571
					{"type":"Identifier","name":"f","range":[4,5]},
572
					{"type":"ObjectExpression","range":[13,24]},
573
					{"type":"Property","kind":"init","range":[13,23]},
574
					{"type":"Identifier","name":"one","range":[9,12]},
575
					{"type":"ObjectExpression","range":[19,23]},
576
					{"type":"Property","kind":"init","range":[20,22]},
577
					{"type":"Identifier","name":"b","range":[20,20]},
578
					{"type":"Literal","range":[21,22],"value":1}],
579
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
580
					{"type":"Identifier","range":[4,5],"value":"f"},
581
					{"type":"Punctuator","range":[6,7],"value":"="},
582
					{"type":"Punctuator","range":[8,9],"value":"{"},
583
					{"type":"Identifier","range":[9,12],"value":"one"},
584
					{"type":"Punctuator","range":[12,13],"value":":"},
585
					{"type":"Punctuator","range":[14,15],"value":"{"},
586
					{"type":"Identifier","range":[15,16],"value":"a"},
587
					{"type":"Identifier","range":[17,18],"value":"c"},
588
					{"type":"Identifier","range":[19,20],"value":"b"},
589
					{"type":"Punctuator","range":[20,21],"value":":"},
590
					{"type":"Numeric","range":[21,22],"value":"1"},
591
					{"type":"Punctuator","range":[22,23],"value":"}"},
592
					{"type":"Punctuator","range":[23,24],"value":"}"},
593
					{"type":"Punctuator","range":[24,25],"value":";"}]
343
		},
594
		},
344
		"nested obj prop recovery5": {
595
		
345
			source: "var f = {\none: {\na: d(}\n};",
596
		'obj prop ident recovery - successive nested 1': {
346
			errors: [],
597
			source: 'var f = {one: {a b:1}};',
347
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property -> ObjectExpression -> Property*/]
598
			errors: [{"lineNumber":1,"index":15,"message":"Unexpected token a","token":"a"}],
599
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,23]},
600
					{"type":"VariableDeclarator","range":[7,22]},
601
					{"type":"Identifier","name":"f","range":[4,5]},
602
					{"type":"ObjectExpression","range":[9,22]},
603
					{"type":"Property","kind":"init","range":[13,21]},
604
					{"type":"Identifier","name":"one","range":[9,12]},
605
					{"type":"ObjectExpression","range":[15,21]},
606
					{"type":"Property","kind":"init","range":[18,20]},
607
					{"type":"Identifier","name":"b","range":[18,18]},
608
					{"type":"Literal","range":[19,20],"value":1}],
609
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
610
					{"type":"Identifier","range":[4,5],"value":"f"},
611
					{"type":"Punctuator","range":[6,7],"value":"="},
612
					{"type":"Punctuator","range":[8,9],"value":"{"},
613
					{"type":"Identifier","range":[9,12],"value":"one"},
614
					{"type":"Punctuator","range":[12,13],"value":":"},
615
					{"type":"Punctuator","range":[14,15],"value":"{"},
616
					{"type":"Identifier","range":[15,16],"value":"a"},
617
					{"type":"Identifier","range":[17,18],"value":"b"},
618
					{"type":"Punctuator","range":[18,19],"value":":"},
619
					{"type":"Numeric","range":[19,20],"value":"1"},
620
					{"type":"Punctuator","range":[20,21],"value":"}"},
621
					{"type":"Punctuator","range":[21,22],"value":"}"},
622
					{"type":"Punctuator","range":[22,23],"value":";"}]
348
		},
623
		},
349
		"nested obj prop recovery6": {
624
		
350
			source: "var f = {\none: {\na: {}\n};",
625
		'obj prop ident recovery - successive nested 2': {
351
			errors: [],
626
			source: 'var f = {one: {a b:1,c:2}};',
352
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property -> ObjectExpression -> Property*/]
627
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,27]},
628
					{"type":"VariableDeclarator","range":[7,26]},
629
					{"type":"Identifier","name":"f","range":[4,5]},
630
					{"type":"ObjectExpression","range":[9,26]},
631
					{"type":"Property","kind":"init","range":[13,25]},
632
					{"type":"Identifier","name":"one","range":[9,12]},
633
					{"type":"ObjectExpression","range":[15,25]},
634
					{"type":"Property","kind":"init","range":[18,20]},
635
					{"type":"Identifier","name":"b","range":[18,18]},
636
					{"type":"Literal","range":[19,20],"value":1},
637
					{"type":"Property","kind":"init","range":[21,24]},
638
					{"type":"Identifier","name":"c","range":[21,22]},
639
					{"type":"Literal","range":[23,24],"value":2}],
640
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
641
					{"type":"Identifier","range":[4,5],"value":"f"},
642
					{"type":"Punctuator","range":[6,7],"value":"="},
643
					{"type":"Punctuator","range":[8,9],"value":"{"},
644
					{"type":"Identifier","range":[9,12],"value":"one"},
645
					{"type":"Punctuator","range":[12,13],"value":":"},
646
					{"type":"Punctuator","range":[14,15],"value":"{"},
647
					{"type":"Identifier","range":[15,16],"value":"a"},
648
					{"type":"Identifier","range":[17,18],"value":"b"},
649
					{"type":"Punctuator","range":[18,19],"value":":"},
650
					{"type":"Numeric","range":[19,20],"value":"1"},
651
					{"type":"Punctuator","range":[20,21],"value":","},
652
					{"type":"Identifier","range":[21,22],"value":"c"},
653
					{"type":"Punctuator","range":[22,23],"value":":"},
654
					{"type":"Numeric","range":[23,24],"value":"2"},
655
					{"type":"Punctuator","range":[24,25],"value":"}"},
656
					{"type":"Punctuator","range":[25,26],"value":"}"},
657
					{"type":"Punctuator","range":[26,27],"value":";"}],
658
			errors: [{"lineNumber":1,"index":15,"message":"Unexpected token a","token":"a"}]
353
		},
659
		},
354
		"nested obj prop recovery7": {
660
		
355
			source: "var f = {\none: {\na: d(c.)\n};",
661
		'obj prop ident recovery - successive nested 3': {
356
			errors: [],
662
			source: 'var f = {one: {b: 1,a c:2}};',
357
			nodes: [/*VariableDelcaration -> VariableDeclarator -> ObjectExpression -> Property -> ObjectExpression -> Property*/]
663
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,28]},
358
		}
664
					{"type":"VariableDeclarator","range":[7,27]},
665
					{"type":"Identifier","name":"f","range":[4,5]},
666
					{"type":"ObjectExpression","range":[9,27]},
667
					{"type":"Property","kind":"init","range":[13,26]},
668
					{"type":"Identifier","name":"one","range":[9,12]},
669
					{"type":"ObjectExpression","range":[20,26]},
670
					{"type":"Property","kind":"init","range":[15,19]},
671
					{"type":"Identifier","name":"b","range":[15,16]},
672
					{"type":"Literal","range":[18,19],"value":1},
673
					{"type":"Property","kind":"init","range":[23,25]},
674
					{"type":"Identifier","name":"c","range":[23,23]},
675
					{"type":"Literal","range":[24,25],"value":2}],
676
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
677
					{"type":"Identifier","range":[4,5],"value":"f"},
678
					{"type":"Punctuator","range":[6,7],"value":"="},
679
					{"type":"Punctuator","range":[8,9],"value":"{"},
680
					{"type":"Identifier","range":[9,12],"value":"one"},
681
					{"type":"Punctuator","range":[12,13],"value":":"},
682
					{"type":"Punctuator","range":[14,15],"value":"{"},
683
					{"type":"Identifier","range":[15,16],"value":"b"},
684
					{"type":"Punctuator","range":[16,17],"value":":"},
685
					{"type":"Numeric","range":[18,19],"value":"1"},
686
					{"type":"Punctuator","range":[19,20],"value":","},
687
					{"type":"Identifier","range":[20,21],"value":"a"},
688
					{"type":"Identifier","range":[22,23],"value":"c"},
689
					{"type":"Punctuator","range":[23,24],"value":":"},
690
					{"type":"Numeric","range":[24,25],"value":"2"},
691
					{"type":"Punctuator","range":[25,26],"value":"}"},
692
					{"type":"Punctuator","range":[26,27],"value":"}"},
693
					{"type":"Punctuator","range":[27,28],"value":";"}],
694
			errors: [{"lineNumber":1,"index":20,"message":"Unexpected token a","token":"a"}]
695
		},
696
		
697
		'obj prop ident recovery - successive nested 4': {
698
			source: 'var f = {one: {b: 1,c:2,a }};',
699
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,29]},
700
					{"type":"VariableDeclarator","range":[7,28]},
701
					{"type":"Identifier","name":"f","range":[4,5]},
702
					{"type":"ObjectExpression","range":[9,28]},
703
					{"type":"Property","kind":"init","range":[13,27]},
704
					{"type":"Identifier","name":"one","range":[9,12]},
705
					{"type":"ObjectExpression","range":[24,27]},
706
					{"type":"Property","kind":"init","range":[15,19]},
707
					{"type":"Identifier","name":"b","range":[15,16]},
708
					{"type":"Literal","range":[18,19],"value":1},
709
					{"type":"Property","kind":"init","range":[20,23]},
710
					{"type":"Identifier","name":"c","range":[20,21]},
711
					{"type":"Literal","range":[22,23],"value":2}],
712
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
713
					{"type":"Identifier","range":[4,5],"value":"f"},
714
					{"type":"Punctuator","range":[6,7],"value":"="},
715
					{"type":"Punctuator","range":[8,9],"value":"{"},
716
					{"type":"Identifier","range":[9,12],"value":"one"},
717
					{"type":"Punctuator","range":[12,13],"value":":"},
718
					{"type":"Punctuator","range":[14,15],"value":"{"},
719
					{"type":"Identifier","range":[15,16],"value":"b"},
720
					{"type":"Punctuator","range":[16,17],"value":":"},
721
					{"type":"Numeric","range":[18,19],"value":"1"},
722
					{"type":"Punctuator","range":[19,20],"value":","},
723
					{"type":"Identifier","range":[20,21],"value":"c"},
724
					{"type":"Punctuator","range":[21,22],"value":":"},
725
					{"type":"Numeric","range":[22,23],"value":"2"},
726
					{"type":"Punctuator","range":[23,24],"value":","},
727
					{"type":"Identifier","range":[24,25],"value":"a"},
728
					{"type":"Punctuator","range":[26,27],"value":"}"},
729
					{"type":"Punctuator","range":[27,28],"value":"}"},
730
					{"type":"Punctuator","range":[28,29],"value":";"}],
731
			errors: [{"lineNumber":1,"index":24,"message":"Unexpected token a","token":"a"}]
732
		},
733
		
734
		'obj prop ident recovery - successive nested 5': {
735
			source: 'var f = {one: {d b: 1,c:2,a }};',
736
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,31]},
737
					{"type":"VariableDeclarator","range":[7,30]},
738
					{"type":"Identifier","name":"f","range":[4,5]},
739
					{"type":"ObjectExpression","range":[13,30]},
740
					{"type":"Property","kind":"init","range":[13,29]},
741
					{"type":"Identifier","name":"one","range":[9,12]},
742
					{"type":"ObjectExpression","range":[26,29]},
743
					{"type":"Property","kind":"init","range":[18,21]},
744
					{"type":"Identifier","name":"b","range":[18,18]},
745
					{"type":"Literal","range":[20,21],"value":1},
746
					{"type":"Property","kind":"init","range":[22,25]},
747
					{"type":"Identifier","name":"c","range":[22,23]},
748
					{"type":"Literal","range":[24,25],"value":2}],
749
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
750
					{"type":"Identifier","range":[4,5],"value":"f"},
751
					{"type":"Punctuator","range":[6,7],"value":"="},
752
					{"type":"Punctuator","range":[8,9],"value":"{"},
753
					{"type":"Identifier","range":[9,12],"value":"one"},
754
					{"type":"Punctuator","range":[12,13],"value":":"},
755
					{"type":"Punctuator","range":[14,15],"value":"{"},
756
					{"type":"Identifier","range":[15,16],"value":"d"},
757
					{"type":"Identifier","range":[17,18],"value":"b"},
758
					{"type":"Punctuator","range":[18,19],"value":":"},
759
					{"type":"Numeric","range":[20,21],"value":"1"},
760
					{"type":"Punctuator","range":[21,22],"value":","},
761
					{"type":"Identifier","range":[22,23],"value":"c"},
762
					{"type":"Punctuator","range":[23,24],"value":":"},
763
					{"type":"Numeric","range":[24,25],"value":"2"},
764
					{"type":"Punctuator","range":[25,26],"value":","},
765
					{"type":"Identifier","range":[26,27],"value":"a"},
766
					{"type":"Punctuator","range":[28,29],"value":"}"},
767
					{"type":"Punctuator","range":[29,30],"value":"}"},
768
					{"type":"Punctuator","range":[30,31],"value":";"}],
769
			errors: [{"lineNumber":1,"index":15,"message":"Unexpected token d","token":"d"},
770
					{"lineNumber":1,"index":26,"message":"Unexpected token a","token":"a"}]
771
		},
772
		
773
		'obj prop ident recovery - successive nested 6': {
774
			source: 'var f = {two one: {d b: 1,c:2,a }};',
775
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,35]},
776
					{"type":"VariableDeclarator","range":[8,34]},
777
					{"type":"Identifier","name":"f","range":[4,5]},
778
					{"type":"ObjectExpression","range":[17,34]},
779
					{"type":"Property","kind":"init","range":[17,33]},
780
					{"type":"Identifier","name":"one","range":[16,16]},
781
					{"type":"ObjectExpression","range":[30,33]},
782
					{"type":"Property","kind":"init","range":[22,25]},
783
					{"type":"Identifier","name":"b","range":[22,22]},
784
					{"type":"Literal","range":[24,25],"value":1},
785
					{"type":"Property","kind":"init","range":[26,29]},
786
					{"type":"Identifier","name":"c","range":[26,27]},
787
					{"type":"Literal","range":[28,29],"value":2}],
788
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
789
					{"type":"Identifier","range":[4,5],"value":"f"},
790
					{"type":"Punctuator","range":[6,7],"value":"="},
791
					{"type":"Punctuator","range":[8,9],"value":"{"},
792
					{"type":"Identifier","range":[9,12],"value":"two"},
793
					{"type":"Identifier","range":[13,16],"value":"one"},
794
					{"type":"Punctuator","range":[16,17],"value":":"},
795
					{"type":"Punctuator","range":[18,19],"value":"{"},
796
					{"type":"Identifier","range":[19,20],"value":"d"},
797
					{"type":"Identifier","range":[21,22],"value":"b"},
798
					{"type":"Punctuator","range":[22,23],"value":":"},
799
					{"type":"Numeric","range":[24,25],"value":"1"},
800
					{"type":"Punctuator","range":[25,26],"value":","},
801
					{"type":"Identifier","range":[26,27],"value":"c"},
802
					{"type":"Punctuator","range":[27,28],"value":":"},
803
					{"type":"Numeric","range":[28,29],"value":"2"},
804
					{"type":"Punctuator","range":[29,30],"value":","},
805
					{"type":"Identifier","range":[30,31],"value":"a"},
806
					{"type":"Punctuator","range":[32,33],"value":"}"},
807
					{"type":"Punctuator","range":[33,34],"value":"}"},
808
					{"type":"Punctuator","range":[34,35],"value":";"}],
809
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token two","token":"two"},
810
					{"lineNumber":1,"index":19,"message":"Unexpected token d","token":"d"},
811
					{"lineNumber":1,"index":30,"message":"Unexpected token a","token":"a"}]
812
		},
813
		
814
		'obj prop ident recovery - successive nested 7': {
815
			source: 'var f = {two three one: {d b: 1,c:2,a }};',
816
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[8,41]},
817
					{"type":"VariableDeclarator","range":[8,40]},
818
					{"type":"Identifier","name":"f","range":[4,5]},
819
					{"type":"ObjectExpression","range":[23,40]},
820
					{"type":"Property","kind":"init","range":[23,39]},
821
					{"type":"Identifier","name":"one","range":[22,22]},
822
					{"type":"ObjectExpression","range":[36,39]},
823
					{"type":"Property","kind":"init","range":[28,31]},
824
					{"type":"Identifier","name":"b","range":[28,28]},
825
					{"type":"Literal","range":[30,31],"value":1},
826
					{"type":"Property","kind":"init","range":[32,35]},
827
					{"type":"Identifier","name":"c","range":[32,33]},
828
					{"type":"Literal","range":[34,35],"value":2}],
829
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
830
					{"type":"Identifier","range":[4,5],"value":"f"},
831
					{"type":"Punctuator","range":[6,7],"value":"="},
832
					{"type":"Punctuator","range":[8,9],"value":"{"},
833
					{"type":"Identifier","range":[9,12],"value":"two"},
834
					{"type":"Identifier","range":[13,18],"value":"three"},
835
					{"type":"Identifier","range":[19,22],"value":"one"},
836
					{"type":"Punctuator","range":[22,23],"value":":"},
837
					{"type":"Punctuator","range":[24,25],"value":"{"},
838
					{"type":"Identifier","range":[25,26],"value":"d"},
839
					{"type":"Identifier","range":[27,28],"value":"b"},
840
					{"type":"Punctuator","range":[28,29],"value":":"},
841
					{"type":"Numeric","range":[30,31],"value":"1"},
842
					{"type":"Punctuator","range":[31,32],"value":","},
843
					{"type":"Identifier","range":[32,33],"value":"c"},
844
					{"type":"Punctuator","range":[33,34],"value":":"},
845
					{"type":"Numeric","range":[34,35],"value":"2"},
846
					{"type":"Punctuator","range":[35,36],"value":","},
847
					{"type":"Identifier","range":[36,37],"value":"a"},
848
					{"type":"Punctuator","range":[38,39],"value":"}"},
849
					{"type":"Punctuator","range":[39,40],"value":"}"},
850
					{"type":"Punctuator","range":[40,41],"value":";"}],
851
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token two","token":"two"},
852
					{"lineNumber":1,"index":13,"message":"Unexpected token three","token":"three"},
853
					{"lineNumber":1,"index":25,"message":"Unexpected token d","token":"d"},
854
					{"lineNumber":1,"index":36,"message":"Unexpected token a","token":"a"}]
855
		},
856
		
857
		'obj prop ident recovery - func decl 1': {
858
			source: 'function f(){} f({a});',
859
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
860
					{"type":"Identifier","name":"f","range":[9,10]},
861
					{"type":"BlockStatement","range":[12,14]},
862
					{"type":"ExpressionStatement","range":[15,22]},
863
					{"type":"CallExpression","range":[15,21]},
864
					{"type":"Identifier","name":"f","range":[15,16]},
865
					{"type":"ObjectExpression","range":[18,20]}],
866
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
867
					{"type":"Identifier","range":[9,10],"value":"f"},
868
					{"type":"Punctuator","range":[10,11],"value":"("},
869
					{"type":"Punctuator","range":[11,12],"value":")"},
870
					{"type":"Punctuator","range":[12,13],"value":"{"},
871
					{"type":"Punctuator","range":[13,14],"value":"}"},
872
					{"type":"Identifier","range":[15,16],"value":"f"},
873
					{"type":"Punctuator","range":[16,17],"value":"("},
874
					{"type":"Punctuator","range":[17,18],"value":"{"},
875
					{"type":"Identifier","range":[18,19],"value":"a"},
876
					{"type":"Punctuator","range":[19,20],"value":"}"},
877
					{"type":"Punctuator","range":[20,21],"value":")"},
878
					{"type":"Punctuator","range":[21,22],"value":";"}],
879
			errors: [{"lineNumber":1,"index":18,"message":"Unexpected token a","token":"a"}]
880
		},
881
		
882
		'obj prop ident recovery - func decl 2': {
883
			source: 'function f(){} f({a b:1});',
884
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
885
					{"type":"Identifier","name":"f","range":[9,10]},
886
					{"type":"BlockStatement","range":[12,14]},
887
					{"type":"ExpressionStatement","range":[15,26]},
888
					{"type":"CallExpression","range":[15,25]},
889
					{"type":"Identifier","name":"f","range":[15,16]},
890
					{"type":"ObjectExpression","range":[18,24]},
891
					{"type":"Property","kind":"init","range":[21,23]},
892
					{"type":"Identifier","name":"b","range":[21,21]},
893
					{"type":"Literal","range":[22,23],"value":1}],
894
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
895
					{"type":"Identifier","range":[9,10],"value":"f"},
896
					{"type":"Punctuator","range":[10,11],"value":"("},
897
					{"type":"Punctuator","range":[11,12],"value":")"},
898
					{"type":"Punctuator","range":[12,13],"value":"{"},
899
					{"type":"Punctuator","range":[13,14],"value":"}"},
900
					{"type":"Identifier","range":[15,16],"value":"f"},
901
					{"type":"Punctuator","range":[16,17],"value":"("},
902
					{"type":"Punctuator","range":[17,18],"value":"{"},
903
					{"type":"Identifier","range":[18,19],"value":"a"},
904
					{"type":"Identifier","range":[20,21],"value":"b"},
905
					{"type":"Punctuator","range":[21,22],"value":":"},
906
					{"type":"Numeric","range":[22,23],"value":"1"},
907
					{"type":"Punctuator","range":[23,24],"value":"}"},
908
					{"type":"Punctuator","range":[24,25],"value":")"},
909
					{"type":"Punctuator","range":[25,26],"value":";"}],
910
			errors: [{"lineNumber":1,"index":18,"message":"Unexpected token a","token":"a"}]
911
		},
912
		
913
		'obj prop ident recovery - func decl 3': {
914
			source: 'function f(){} f({a b:1,c:2});',
915
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
916
					{"type":"Identifier","name":"f","range":[9,10]},
917
					{"type":"BlockStatement","range":[12,14]},
918
					{"type":"ExpressionStatement","range":[15,30]},
919
					{"type":"CallExpression","range":[15,29]},
920
					{"type":"Identifier","name":"f","range":[15,16]},
921
					{"type":"ObjectExpression","range":[18,28]},
922
					{"type":"Property","kind":"init","range":[21,23]},
923
					{"type":"Identifier","name":"b","range":[21,21]},
924
					{"type":"Literal","range":[22,23],"value":1},
925
					{"type":"Property","kind":"init","range":[24,27]},
926
					{"type":"Identifier","name":"c","range":[24,25]},
927
					{"type":"Literal","range":[26,27],"value":2}],
928
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
929
					{"type":"Identifier","range":[9,10],"value":"f"},
930
					{"type":"Punctuator","range":[10,11],"value":"("},
931
					{"type":"Punctuator","range":[11,12],"value":")"},
932
					{"type":"Punctuator","range":[12,13],"value":"{"},
933
					{"type":"Punctuator","range":[13,14],"value":"}"},
934
					{"type":"Identifier","range":[15,16],"value":"f"},
935
					{"type":"Punctuator","range":[16,17],"value":"("},
936
					{"type":"Punctuator","range":[17,18],"value":"{"},
937
					{"type":"Identifier","range":[18,19],"value":"a"},
938
					{"type":"Identifier","range":[20,21],"value":"b"},
939
					{"type":"Punctuator","range":[21,22],"value":":"},
940
					{"type":"Numeric","range":[22,23],"value":"1"},
941
					{"type":"Punctuator","range":[23,24],"value":","},
942
					{"type":"Identifier","range":[24,25],"value":"c"},
943
					{"type":"Punctuator","range":[25,26],"value":":"},
944
					{"type":"Numeric","range":[26,27],"value":"2"},
945
					{"type":"Punctuator","range":[27,28],"value":"}"},
946
					{"type":"Punctuator","range":[28,29],"value":")"},
947
					{"type":"Punctuator","range":[29,30],"value":";"}],
948
			errors: [{"lineNumber":1,"index":18,"message":"Unexpected token a","token":"a"}]
949
		},
950
		
951
		'obj prop ident recovery - func decl 4': {
952
			source: 'function f(){} f({b:1,a});',
953
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
954
					{"type":"Identifier","name":"f","range":[9,10]},
955
					{"type":"BlockStatement","range":[12,14]},
956
					{"type":"ExpressionStatement","range":[15,26]},
957
					{"type":"CallExpression","range":[15,25]},
958
					{"type":"Identifier","name":"f","range":[15,16]},
959
					{"type":"ObjectExpression","range":[22,24]},
960
					{"type":"Property","kind":"init","range":[18,21]},
961
					{"type":"Identifier","name":"b","range":[18,19]},
962
					{"type":"Literal","range":[20,21],"value":1}],
963
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
964
					{"type":"Identifier","range":[9,10],"value":"f"},
965
					{"type":"Punctuator","range":[10,11],"value":"("},
966
					{"type":"Punctuator","range":[11,12],"value":")"},
967
					{"type":"Punctuator","range":[12,13],"value":"{"},
968
					{"type":"Punctuator","range":[13,14],"value":"}"},
969
					{"type":"Identifier","range":[15,16],"value":"f"},
970
					{"type":"Punctuator","range":[16,17],"value":"("},
971
					{"type":"Punctuator","range":[17,18],"value":"{"},
972
					{"type":"Identifier","range":[18,19],"value":"b"},
973
					{"type":"Punctuator","range":[19,20],"value":":"},
974
					{"type":"Numeric","range":[20,21],"value":"1"},
975
					{"type":"Punctuator","range":[21,22],"value":","},
976
					{"type":"Identifier","range":[22,23],"value":"a"},
977
					{"type":"Punctuator","range":[23,24],"value":"}"},
978
					{"type":"Punctuator","range":[24,25],"value":")"},
979
					{"type":"Punctuator","range":[25,26],"value":";"}],
980
			errors: [{"lineNumber":1,"index":22,"message":"Unexpected token a","token":"a"}]
981
		},
982
		
983
		'obj prop ident recovery - func decl 5': {
984
			source: 'function f(){} f({b:1,c:2,a});',
985
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
986
					{"type":"Identifier","name":"f","range":[9,10]},
987
					{"type":"BlockStatement","range":[12,14]},
988
					{"type":"ExpressionStatement","range":[15,30]},
989
					{"type":"CallExpression","range":[15,29]},
990
					{"type":"Identifier","name":"f","range":[15,16]},
991
					{"type":"ObjectExpression","range":[26,28]},
992
					{"type":"Property","kind":"init","range":[18,21]},
993
					{"type":"Identifier","name":"b","range":[18,19]},
994
					{"type":"Literal","range":[20,21],"value":1},
995
					{"type":"Property","kind":"init","range":[22,25]},
996
					{"type":"Identifier","name":"c","range":[22,23]},
997
					{"type":"Literal","range":[24,25],"value":2}],
998
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
999
					{"type":"Identifier","range":[9,10],"value":"f"},
1000
					{"type":"Punctuator","range":[10,11],"value":"("},
1001
					{"type":"Punctuator","range":[11,12],"value":")"},
1002
					{"type":"Punctuator","range":[12,13],"value":"{"},
1003
					{"type":"Punctuator","range":[13,14],"value":"}"},
1004
					{"type":"Identifier","range":[15,16],"value":"f"},
1005
					{"type":"Punctuator","range":[16,17],"value":"("},
1006
					{"type":"Punctuator","range":[17,18],"value":"{"},
1007
					{"type":"Identifier","range":[18,19],"value":"b"},
1008
					{"type":"Punctuator","range":[19,20],"value":":"},
1009
					{"type":"Numeric","range":[20,21],"value":"1"},
1010
					{"type":"Punctuator","range":[21,22],"value":","},
1011
					{"type":"Identifier","range":[22,23],"value":"c"},
1012
					{"type":"Punctuator","range":[23,24],"value":":"},
1013
					{"type":"Numeric","range":[24,25],"value":"2"},
1014
					{"type":"Punctuator","range":[25,26],"value":","},
1015
					{"type":"Identifier","range":[26,27],"value":"a"},
1016
					{"type":"Punctuator","range":[27,28],"value":"}"},
1017
					{"type":"Punctuator","range":[28,29],"value":")"},
1018
					{"type":"Punctuator","range":[29,30],"value":";"}],
1019
			errors: [{"lineNumber":1,"index":26,"message":"Unexpected token a","token":"a"}]
1020
		},
1021
		
1022
		'obj prop ident recovery - func decl 6': {
1023
			source: 'function f(){} f({a b c:2});',
1024
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
1025
					{"type":"Identifier","name":"f","range":[9,10]},
1026
					{"type":"BlockStatement","range":[12,14]},
1027
					{"type":"ExpressionStatement","range":[15,28]},
1028
					{"type":"CallExpression","range":[15,27]},
1029
					{"type":"Identifier","name":"f","range":[15,16]},
1030
					{"type":"ObjectExpression","range":[22,26]},
1031
					{"type":"Property","kind":"init","range":[23,25]},
1032
					{"type":"Identifier","name":"c","range":[23,23]},
1033
					{"type":"Literal","range":[24,25],"value":2}],
1034
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1035
					{"type":"Identifier","range":[9,10],"value":"f"},
1036
					{"type":"Punctuator","range":[10,11],"value":"("},
1037
					{"type":"Punctuator","range":[11,12],"value":")"},
1038
					{"type":"Punctuator","range":[12,13],"value":"{"},
1039
					{"type":"Punctuator","range":[13,14],"value":"}"},
1040
					{"type":"Identifier","range":[15,16],"value":"f"},
1041
					{"type":"Punctuator","range":[16,17],"value":"("},
1042
					{"type":"Punctuator","range":[17,18],"value":"{"},
1043
					{"type":"Identifier","range":[18,19],"value":"a"},
1044
					{"type":"Identifier","range":[20,21],"value":"b"},
1045
					{"type":"Identifier","range":[22,23],"value":"c"},
1046
					{"type":"Punctuator","range":[23,24],"value":":"},
1047
					{"type":"Numeric","range":[24,25],"value":"2"},
1048
					{"type":"Punctuator","range":[25,26],"value":"}"},
1049
					{"type":"Punctuator","range":[26,27],"value":")"},
1050
					{"type":"Punctuator","range":[27,28],"value":";"}],
1051
			errors: [{"lineNumber":1,"index":18,"message":"Unexpected token a","token":"a"},
1052
					{"lineNumber":1,"index":20,"message":"Unexpected token b","token":"b"}]
1053
		},
1054
		
1055
		'obj prop ident recovery - func decl 7': {
1056
			source: 'function f(){} f({a b:1,c});',
1057
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
1058
					{"type":"Identifier","name":"f","range":[9,10]},
1059
					{"type":"BlockStatement","range":[12,14]},
1060
					{"type":"ExpressionStatement","range":[15,28]},
1061
					{"type":"CallExpression","range":[15,27]},
1062
					{"type":"Identifier","name":"f","range":[15,16]},
1063
					{"type":"ObjectExpression","range":[24,26]},
1064
					{"type":"Property","kind":"init","range":[21,23]},
1065
					{"type":"Identifier","name":"b","range":[21,21]},
1066
					{"type":"Literal","range":[22,23],"value":1}],
1067
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1068
					{"type":"Identifier","range":[9,10],"value":"f"},
1069
					{"type":"Punctuator","range":[10,11],"value":"("},
1070
					{"type":"Punctuator","range":[11,12],"value":")"},
1071
					{"type":"Punctuator","range":[12,13],"value":"{"},
1072
					{"type":"Punctuator","range":[13,14],"value":"}"},
1073
					{"type":"Identifier","range":[15,16],"value":"f"},
1074
					{"type":"Punctuator","range":[16,17],"value":"("},
1075
					{"type":"Punctuator","range":[17,18],"value":"{"},
1076
					{"type":"Identifier","range":[18,19],"value":"a"},
1077
					{"type":"Identifier","range":[20,21],"value":"b"},
1078
					{"type":"Punctuator","range":[21,22],"value":":"},
1079
					{"type":"Numeric","range":[22,23],"value":"1"},
1080
					{"type":"Punctuator","range":[23,24],"value":","},
1081
					{"type":"Identifier","range":[24,25],"value":"c"},
1082
					{"type":"Punctuator","range":[25,26],"value":"}"},
1083
					{"type":"Punctuator","range":[26,27],"value":")"},
1084
					{"type":"Punctuator","range":[27,28],"value":";"}],
1085
			errors: [{"lineNumber":1,"index":18,"message":"Unexpected token a","token":"a"},
1086
					{"lineNumber":1,"index":24,"message":"Unexpected token c","token":"c"}]
1087
		},
1088
		
1089
		'obj prop ident recovery - func decl nested 1': {
1090
			source: 'function f(){} f({one: {a}});',
1091
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
1092
					{"type":"Identifier","name":"f","range":[9,10]},
1093
					{"type":"BlockStatement","range":[12,14]},
1094
					{"type":"ExpressionStatement","range":[15,29]},
1095
					{"type":"CallExpression","range":[15,28]},
1096
					{"type":"Identifier","name":"f","range":[15,16]},
1097
					{"type":"ObjectExpression","range":[18,27]},
1098
					{"type":"Property","kind":"init","range":[22,26]},
1099
					{"type":"Identifier","name":"one","range":[18,21]},
1100
					{"type":"ObjectExpression","range":[24,26]}],
1101
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1102
					{"type":"Identifier","range":[9,10],"value":"f"},
1103
					{"type":"Punctuator","range":[10,11],"value":"("},
1104
					{"type":"Punctuator","range":[11,12],"value":")"},
1105
					{"type":"Punctuator","range":[12,13],"value":"{"},
1106
					{"type":"Punctuator","range":[13,14],"value":"}"},
1107
					{"type":"Identifier","range":[15,16],"value":"f"},
1108
					{"type":"Punctuator","range":[16,17],"value":"("},
1109
					{"type":"Punctuator","range":[17,18],"value":"{"},
1110
					{"type":"Identifier","range":[18,21],"value":"one"},
1111
					{"type":"Punctuator","range":[21,22],"value":":"},
1112
					{"type":"Punctuator","range":[23,24],"value":"{"},
1113
					{"type":"Identifier","range":[24,25],"value":"a"},
1114
					{"type":"Punctuator","range":[25,26],"value":"}"},
1115
					{"type":"Punctuator","range":[26,27],"value":"}"},
1116
					{"type":"Punctuator","range":[27,28],"value":")"},
1117
					{"type":"Punctuator","range":[28,29],"value":";"}],
1118
			errors: [{"lineNumber":1,"index":24,"message":"Unexpected token a","token":"a"}]
1119
		},
1120
		
1121
		'obj prop ident recovery - func decl nested 2': {
1122
			source: 'function f(){} f({one: {a b:1}});',
1123
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
1124
					{"type":"Identifier","name":"f","range":[9,10]},
1125
					{"type":"BlockStatement","range":[12,14]},
1126
					{"type":"ExpressionStatement","range":[15,33]},
1127
					{"type":"CallExpression","range":[15,32]},
1128
					{"type":"Identifier","name":"f","range":[15,16]},
1129
					{"type":"ObjectExpression","range":[18,31]},
1130
					{"type":"Property","kind":"init","range":[22,30]},
1131
					{"type":"Identifier","name":"one","range":[18,21]},
1132
					{"type":"ObjectExpression","range":[24,30]},
1133
					{"type":"Property","kind":"init","range":[27,29]},
1134
					{"type":"Identifier","name":"b","range":[27,27]},
1135
					{"type":"Literal","range":[28,29],"value":1}],
1136
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1137
					{"type":"Identifier","range":[9,10],"value":"f"},
1138
					{"type":"Punctuator","range":[10,11],"value":"("},
1139
					{"type":"Punctuator","range":[11,12],"value":")"},
1140
					{"type":"Punctuator","range":[12,13],"value":"{"},
1141
					{"type":"Punctuator","range":[13,14],"value":"}"},
1142
					{"type":"Identifier","range":[15,16],"value":"f"},
1143
					{"type":"Punctuator","range":[16,17],"value":"("},
1144
					{"type":"Punctuator","range":[17,18],"value":"{"},
1145
					{"type":"Identifier","range":[18,21],"value":"one"},
1146
					{"type":"Punctuator","range":[21,22],"value":":"},
1147
					{"type":"Punctuator","range":[23,24],"value":"{"},
1148
					{"type":"Identifier","range":[24,25],"value":"a"},
1149
					{"type":"Identifier","range":[26,27],"value":"b"},
1150
					{"type":"Punctuator","range":[27,28],"value":":"},
1151
					{"type":"Numeric","range":[28,29],"value":"1"},
1152
					{"type":"Punctuator","range":[29,30],"value":"}"},
1153
					{"type":"Punctuator","range":[30,31],"value":"}"},
1154
					{"type":"Punctuator","range":[31,32],"value":")"},
1155
					{"type":"Punctuator","range":[32,33],"value":";"}],
1156
			errors: [{"lineNumber":1,"index":24,"message":"Unexpected token a","token":"a"}]
1157
		},
1158
		
1159
		'obj prop ident recovery - func decl nested 3': {
1160
			source: 'function f(){} f({one: {a b:1,c:2}});',
1161
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
1162
					{"type":"Identifier","name":"f","range":[9,10]},
1163
					{"type":"BlockStatement","range":[12,14]},
1164
					{"type":"ExpressionStatement","range":[15,37]},
1165
					{"type":"CallExpression","range":[15,36]},
1166
					{"type":"Identifier","name":"f","range":[15,16]},
1167
					{"type":"ObjectExpression","range":[18,35]},
1168
					{"type":"Property","kind":"init","range":[22,34]},
1169
					{"type":"Identifier","name":"one","range":[18,21]},
1170
					{"type":"ObjectExpression","range":[24,34]},
1171
					{"type":"Property","kind":"init","range":[27,29]},
1172
					{"type":"Identifier","name":"b","range":[27,27]},
1173
					{"type":"Literal","range":[28,29],"value":1},
1174
					{"type":"Property","kind":"init","range":[30,33]},
1175
					{"type":"Identifier","name":"c","range":[30,31]},
1176
					{"type":"Literal","range":[32,33],"value":2}],
1177
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1178
					{"type":"Identifier","range":[9,10],"value":"f"},
1179
					{"type":"Punctuator","range":[10,11],"value":"("},
1180
					{"type":"Punctuator","range":[11,12],"value":")"},
1181
					{"type":"Punctuator","range":[12,13],"value":"{"},
1182
					{"type":"Punctuator","range":[13,14],"value":"}"},
1183
					{"type":"Identifier","range":[15,16],"value":"f"},
1184
					{"type":"Punctuator","range":[16,17],"value":"("},
1185
					{"type":"Punctuator","range":[17,18],"value":"{"},
1186
					{"type":"Identifier","range":[18,21],"value":"one"},
1187
					{"type":"Punctuator","range":[21,22],"value":":"},
1188
					{"type":"Punctuator","range":[23,24],"value":"{"},
1189
					{"type":"Identifier","range":[24,25],"value":"a"},
1190
					{"type":"Identifier","range":[26,27],"value":"b"},
1191
					{"type":"Punctuator","range":[27,28],"value":":"},
1192
					{"type":"Numeric","range":[28,29],"value":"1"},
1193
					{"type":"Punctuator","range":[29,30],"value":","},
1194
					{"type":"Identifier","range":[30,31],"value":"c"},
1195
					{"type":"Punctuator","range":[31,32],"value":":"},
1196
					{"type":"Numeric","range":[32,33],"value":"2"},
1197
					{"type":"Punctuator","range":[33,34],"value":"}"},
1198
					{"type":"Punctuator","range":[34,35],"value":"}"},
1199
					{"type":"Punctuator","range":[35,36],"value":")"},
1200
					{"type":"Punctuator","range":[36,37],"value":";"}],
1201
			errors: [{"lineNumber":1,"index":24,"message":"Unexpected token a","token":"a"}]
1202
		},
1203
		
1204
		'obj prop ident recovery - func decl nested 4': {
1205
			source: 'function f(){} f({one: {a b c:2}});',
1206
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
1207
					{"type":"Identifier","name":"f","range":[9,10]},
1208
					{"type":"BlockStatement","range":[12,14]},
1209
					{"type":"ExpressionStatement","range":[15,35]},
1210
					{"type":"CallExpression","range":[15,34]},
1211
					{"type":"Identifier","name":"f","range":[15,16]},
1212
					{"type":"ObjectExpression","range":[22,33]},
1213
					{"type":"Property","kind":"init","range":[22,32]},
1214
					{"type":"Identifier","name":"one","range":[18,21]},
1215
					{"type":"ObjectExpression","range":[28,32]},
1216
					{"type":"Property","kind":"init","range":[29,31]},
1217
					{"type":"Identifier","name":"c","range":[29,29]},
1218
					{"type":"Literal","range":[30,31],"value":2}],
1219
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1220
					{"type":"Identifier","range":[9,10],"value":"f"},
1221
					{"type":"Punctuator","range":[10,11],"value":"("},
1222
					{"type":"Punctuator","range":[11,12],"value":")"},
1223
					{"type":"Punctuator","range":[12,13],"value":"{"},
1224
					{"type":"Punctuator","range":[13,14],"value":"}"},
1225
					{"type":"Identifier","range":[15,16],"value":"f"},
1226
					{"type":"Punctuator","range":[16,17],"value":"("},
1227
					{"type":"Punctuator","range":[17,18],"value":"{"},
1228
					{"type":"Identifier","range":[18,21],"value":"one"},
1229
					{"type":"Punctuator","range":[21,22],"value":":"},
1230
					{"type":"Punctuator","range":[23,24],"value":"{"},
1231
					{"type":"Identifier","range":[24,25],"value":"a"},
1232
					{"type":"Identifier","range":[26,27],"value":"b"},
1233
					{"type":"Identifier","range":[28,29],"value":"c"},
1234
					{"type":"Punctuator","range":[29,30],"value":":"},
1235
					{"type":"Numeric","range":[30,31],"value":"2"},
1236
					{"type":"Punctuator","range":[31,32],"value":"}"},
1237
					{"type":"Punctuator","range":[32,33],"value":"}"},
1238
					{"type":"Punctuator","range":[33,34],"value":")"},
1239
					{"type":"Punctuator","range":[34,35],"value":";"}],
1240
			errors: [{"lineNumber":1,"index":24,"message":"Unexpected token a","token":"a"},
1241
					{"lineNumber":1,"index":26,"message":"Unexpected token b","token":"b"}]
1242
		},
1243
		
1244
		'obj prop ident recovery - func decl nested 5': {
1245
			source: 'function f(){} f({two one: {a b:1}});',
1246
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
1247
					{"type":"Identifier","name":"f","range":[9,10]},
1248
					{"type":"BlockStatement","range":[12,14]},
1249
					{"type":"ExpressionStatement","range":[15,37]},
1250
					{"type":"CallExpression","range":[15,36]},
1251
					{"type":"Identifier","name":"f","range":[15,16]},
1252
					{"type":"ObjectExpression","range":[25,35]},
1253
					{"type":"Property","kind":"init","range":[26,34]},
1254
					{"type":"Identifier","name":"one","range":[25,25]},
1255
					{"type":"ObjectExpression","range":[28,34]},
1256
					{"type":"Property","kind":"init","range":[31,33]},
1257
					{"type":"Identifier","name":"b","range":[31,31]},
1258
					{"type":"Literal","range":[32,33],"value":1}],
1259
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1260
					{"type":"Identifier","range":[9,10],"value":"f"},
1261
					{"type":"Punctuator","range":[10,11],"value":"("},
1262
					{"type":"Punctuator","range":[11,12],"value":")"},
1263
					{"type":"Punctuator","range":[12,13],"value":"{"},
1264
					{"type":"Punctuator","range":[13,14],"value":"}"},
1265
					{"type":"Identifier","range":[15,16],"value":"f"},
1266
					{"type":"Punctuator","range":[16,17],"value":"("},
1267
					{"type":"Punctuator","range":[17,18],"value":"{"},
1268
					{"type":"Identifier","range":[18,21],"value":"two"},
1269
					{"type":"Identifier","range":[22,25],"value":"one"},
1270
					{"type":"Punctuator","range":[25,26],"value":":"},
1271
					{"type":"Punctuator","range":[27,28],"value":"{"},
1272
					{"type":"Identifier","range":[28,29],"value":"a"},
1273
					{"type":"Identifier","range":[30,31],"value":"b"},
1274
					{"type":"Punctuator","range":[31,32],"value":":"},
1275
					{"type":"Numeric","range":[32,33],"value":"1"},
1276
					{"type":"Punctuator","range":[33,34],"value":"}"},
1277
					{"type":"Punctuator","range":[34,35],"value":"}"},
1278
					{"type":"Punctuator","range":[35,36],"value":")"},
1279
					{"type":"Punctuator","range":[36,37],"value":";"}],
1280
			errors: [{"lineNumber":1,"index":18,"message":"Unexpected token two","token":"two"},
1281
					{"lineNumber":1,"index":28,"message":"Unexpected token a","token":"a"}]
1282
		},
1283
		
1284
		'obj prop ident recovery - func decl nested 6': {
1285
			source: 'function f(){} f({two one: {a b:1},three});',
1286
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
1287
					{"type":"Identifier","name":"f","range":[9,10]},
1288
					{"type":"BlockStatement","range":[12,14]},
1289
					{"type":"ExpressionStatement","range":[15,43]},
1290
					{"type":"CallExpression","range":[15,42]},
1291
					{"type":"Identifier","name":"f","range":[15,16]},
1292
					{"type":"ObjectExpression","range":[35,41]},
1293
					{"type":"Property","kind":"init","range":[26,34]},
1294
					{"type":"Identifier","name":"one","range":[25,25]},
1295
					{"type":"ObjectExpression","range":[28,34]},
1296
					{"type":"Property","kind":"init","range":[31,33]},
1297
					{"type":"Identifier","name":"b","range":[31,31]},
1298
					{"type":"Literal","range":[32,33],"value":1}],
1299
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1300
					{"type":"Identifier","range":[9,10],"value":"f"},
1301
					{"type":"Punctuator","range":[10,11],"value":"("},
1302
					{"type":"Punctuator","range":[11,12],"value":")"},
1303
					{"type":"Punctuator","range":[12,13],"value":"{"},
1304
					{"type":"Punctuator","range":[13,14],"value":"}"},
1305
					{"type":"Identifier","range":[15,16],"value":"f"},
1306
					{"type":"Punctuator","range":[16,17],"value":"("},
1307
					{"type":"Punctuator","range":[17,18],"value":"{"},
1308
					{"type":"Identifier","range":[18,21],"value":"two"},
1309
					{"type":"Identifier","range":[22,25],"value":"one"},
1310
					{"type":"Punctuator","range":[25,26],"value":":"},
1311
					{"type":"Punctuator","range":[27,28],"value":"{"},
1312
					{"type":"Identifier","range":[28,29],"value":"a"},
1313
					{"type":"Identifier","range":[30,31],"value":"b"},
1314
					{"type":"Punctuator","range":[31,32],"value":":"},
1315
					{"type":"Numeric","range":[32,33],"value":"1"},
1316
					{"type":"Punctuator","range":[33,34],"value":"}"},
1317
					{"type":"Punctuator","range":[34,35],"value":","},
1318
					{"type":"Identifier","range":[35,40],"value":"three"},
1319
					{"type":"Punctuator","range":[40,41],"value":"}"},
1320
					{"type":"Punctuator","range":[41,42],"value":")"},
1321
					{"type":"Punctuator","range":[42,43],"value":";"}],
1322
			errors: [{"lineNumber":1,"index":18,"message":"Unexpected token two","token":"two"},
1323
					{"lineNumber":1,"index":28,"message":"Unexpected token a","token":"a"},
1324
					{"lineNumber":1,"index":35,"message":"Unexpected token three","token":"three"}]
1325
		},
1326
		
1327
		'obj prop ident recovery - return 1': {
1328
			source: 'function f() {return {a};}',
1329
			nodes: [{"type":"FunctionDeclaration","range":[13,26]},
1330
					{"type":"Identifier","name":"f","range":[9,10]},
1331
					{"type":"BlockStatement","range":[14,26]},
1332
					{"type":"ReturnStatement","range":[20,25]},
1333
					{"type":"ObjectExpression","range":[22,24]}],
1334
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1335
					{"type":"Identifier","range":[9,10],"value":"f"},
1336
					{"type":"Punctuator","range":[10,11],"value":"("},
1337
					{"type":"Punctuator","range":[11,12],"value":")"},
1338
					{"type":"Punctuator","range":[13,14],"value":"{"},
1339
					{"type":"Keyword","range":[14,20],"value":"return"},
1340
					{"type":"Punctuator","range":[21,22],"value":"{"},
1341
					{"type":"Identifier","range":[22,23],"value":"a"},
1342
					{"type":"Punctuator","range":[23,24],"value":"}"},
1343
					{"type":"Punctuator","range":[24,25],"value":";"},
1344
					{"type":"Punctuator","range":[25,26],"value":"}"}],
1345
			errors: [{"lineNumber":1,"index":22,"message":"Unexpected token a","token":"a"}]
1346
		},
1347
		
1348
		'obj prop ident recovery - return 2': {
1349
			source: 'function f() {return {a b:1};}',
1350
			nodes: [{"type":"FunctionDeclaration","range":[13,30]},
1351
					{"type":"Identifier","name":"f","range":[9,10]},
1352
					{"type":"BlockStatement","range":[14,30]},
1353
					{"type":"ReturnStatement","range":[20,29]},
1354
					{"type":"ObjectExpression","range":[22,28]},
1355
					{"type":"Property","kind":"init","range":[25,27]},
1356
					{"type":"Identifier","name":"b","range":[25,25]},
1357
					{"type":"Literal","range":[26,27],"value":1}],
1358
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1359
					{"type":"Identifier","range":[9,10],"value":"f"},
1360
					{"type":"Punctuator","range":[10,11],"value":"("},
1361
					{"type":"Punctuator","range":[11,12],"value":")"},
1362
					{"type":"Punctuator","range":[13,14],"value":"{"},
1363
					{"type":"Keyword","range":[14,20],"value":"return"},
1364
					{"type":"Punctuator","range":[21,22],"value":"{"},
1365
					{"type":"Identifier","range":[22,23],"value":"a"},
1366
					{"type":"Identifier","range":[24,25],"value":"b"},
1367
					{"type":"Punctuator","range":[25,26],"value":":"},
1368
					{"type":"Numeric","range":[26,27],"value":"1"},
1369
					{"type":"Punctuator","range":[27,28],"value":"}"},
1370
					{"type":"Punctuator","range":[28,29],"value":";"},
1371
					{"type":"Punctuator","range":[29,30],"value":"}"}],
1372
			errors: [{"lineNumber":1,"index":22,"message":"Unexpected token a","token":"a"}]
1373
		},
1374
		
1375
		'obj prop ident recovery - return 3': {
1376
			source: 'function f() {return {b:1, a c:2};}',
1377
			nodes: [{"type":"FunctionDeclaration","range":[13,35]},
1378
					{"type":"Identifier","name":"f","range":[9,10]},
1379
					{"type":"BlockStatement","range":[14,35]},
1380
					{"type":"ReturnStatement","range":[20,34]},
1381
					{"type":"ObjectExpression","range":[27,33]},
1382
					{"type":"Property","kind":"init","range":[22,25]},
1383
					{"type":"Identifier","name":"b","range":[22,23]},
1384
					{"type":"Literal","range":[24,25],"value":1},
1385
					{"type":"Property","kind":"init","range":[30,32]},
1386
					{"type":"Identifier","name":"c","range":[30,30]},
1387
					{"type":"Literal","range":[31,32],"value":2}],
1388
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1389
					{"type":"Identifier","range":[9,10],"value":"f"},
1390
					{"type":"Punctuator","range":[10,11],"value":"("},
1391
					{"type":"Punctuator","range":[11,12],"value":")"},
1392
					{"type":"Punctuator","range":[13,14],"value":"{"},
1393
					{"type":"Keyword","range":[14,20],"value":"return"},
1394
					{"type":"Punctuator","range":[21,22],"value":"{"},
1395
					{"type":"Identifier","range":[22,23],"value":"b"},
1396
					{"type":"Punctuator","range":[23,24],"value":":"},
1397
					{"type":"Numeric","range":[24,25],"value":"1"},
1398
					{"type":"Punctuator","range":[25,26],"value":","},
1399
					{"type":"Identifier","range":[27,28],"value":"a"},
1400
					{"type":"Identifier","range":[29,30],"value":"c"},
1401
					{"type":"Punctuator","range":[30,31],"value":":"},
1402
					{"type":"Numeric","range":[31,32],"value":"2"},
1403
					{"type":"Punctuator","range":[32,33],"value":"}"},
1404
					{"type":"Punctuator","range":[33,34],"value":";"},
1405
					{"type":"Punctuator","range":[34,35],"value":"}"}],
1406
			errors: [{"lineNumber":1,"index":27,"message":"Unexpected token a","token":"a"}]
1407
		},
1408
		
1409
		'obj prop ident recovery - return 4': {
1410
			source: 'function f() {return {b:1,a c};}',
1411
			nodes: [{"type":"FunctionDeclaration","range":[14,32]},
1412
					{"type":"Identifier","name":"f","range":[9,10]},
1413
					{"type":"BlockStatement","range":[20,32]},
1414
					{"type":"ReturnStatement","range":[20,31]},
1415
					{"type":"ObjectExpression","range":[29,30]},
1416
					{"type":"Property","kind":"init","range":[22,25]},
1417
					{"type":"Identifier","name":"b","range":[22,23]},
1418
					{"type":"Literal","range":[24,25],"value":1}],
1419
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1420
					{"type":"Identifier","range":[9,10],"value":"f"},
1421
					{"type":"Punctuator","range":[10,11],"value":"("},
1422
					{"type":"Punctuator","range":[11,12],"value":")"},
1423
					{"type":"Punctuator","range":[13,14],"value":"{"},
1424
					{"type":"Keyword","range":[14,20],"value":"return"},
1425
					{"type":"Punctuator","range":[21,22],"value":"{"},
1426
					{"type":"Identifier","range":[22,23],"value":"b"},
1427
					{"type":"Punctuator","range":[23,24],"value":":"},
1428
					{"type":"Numeric","range":[24,25],"value":"1"},
1429
					{"type":"Punctuator","range":[25,26],"value":","},
1430
					{"type":"Identifier","range":[26,27],"value":"a"},
1431
					{"type":"Identifier","range":[28,29],"value":"c"},
1432
					{"type":"Punctuator","range":[29,30],"value":"}"},
1433
					{"type":"Punctuator","range":[30,31],"value":";"},
1434
					{"type":"Punctuator","range":[31,32],"value":"}"}],
1435
			errors: [{"lineNumber":1,"index":26,"message":"Unexpected token a","token":"a"},
1436
					{"lineNumber":1,"index":28,"message":"Unexpected token c","token":"c"}]
1437
		},
1438
		
1439
		'obj prop ident recovery - return 5': {
1440
			source: 'function f() {return {a b:1,c};}',
1441
			nodes: [{"type":"FunctionDeclaration","range":[14,32]},
1442
					{"type":"Identifier","name":"f","range":[9,10]},
1443
					{"type":"BlockStatement","range":[20,32]},
1444
					{"type":"ReturnStatement","range":[20,31]},
1445
					{"type":"ObjectExpression","range":[28,30]},
1446
					{"type":"Property","kind":"init","range":[25,27]},
1447
					{"type":"Identifier","name":"b","range":[25,25]},
1448
					{"type":"Literal","range":[26,27],"value":1}],
1449
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1450
					{"type":"Identifier","range":[9,10],"value":"f"},
1451
					{"type":"Punctuator","range":[10,11],"value":"("},
1452
					{"type":"Punctuator","range":[11,12],"value":")"},
1453
					{"type":"Punctuator","range":[13,14],"value":"{"},
1454
					{"type":"Keyword","range":[14,20],"value":"return"},
1455
					{"type":"Punctuator","range":[21,22],"value":"{"},
1456
					{"type":"Identifier","range":[22,23],"value":"a"},
1457
					{"type":"Identifier","range":[24,25],"value":"b"},
1458
					{"type":"Punctuator","range":[25,26],"value":":"},
1459
					{"type":"Numeric","range":[26,27],"value":"1"},
1460
					{"type":"Punctuator","range":[27,28],"value":","},
1461
					{"type":"Identifier","range":[28,29],"value":"c"},
1462
					{"type":"Punctuator","range":[29,30],"value":"}"},
1463
					{"type":"Punctuator","range":[30,31],"value":";"},
1464
					{"type":"Punctuator","range":[31,32],"value":"}"}],
1465
			errors: [{"lineNumber":1,"index":22,"message":"Unexpected token a","token":"a"},
1466
					{"lineNumber":1,"index":28,"message":"Unexpected token c","token":"c"}]
1467
		},
1468
		
1469
		'obj prop ident recovery - return nested 1': {
1470
			source: 'function f() {return {one:{a}};}',
1471
			nodes: [{"type":"FunctionDeclaration","range":[13,32]},
1472
					{"type":"Identifier","name":"f","range":[9,10]},
1473
					{"type":"BlockStatement","range":[14,32]},
1474
					{"type":"ReturnStatement","range":[20,31]},
1475
					{"type":"ObjectExpression","range":[22,30]},
1476
					{"type":"Property","kind":"init","range":[26,29]},
1477
					{"type":"Identifier","name":"one","range":[22,25]},
1478
					{"type":"ObjectExpression","range":[27,29]}],
1479
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1480
					{"type":"Identifier","range":[9,10],"value":"f"},
1481
					{"type":"Punctuator","range":[10,11],"value":"("},
1482
					{"type":"Punctuator","range":[11,12],"value":")"},
1483
					{"type":"Punctuator","range":[13,14],"value":"{"},
1484
					{"type":"Keyword","range":[14,20],"value":"return"},
1485
					{"type":"Punctuator","range":[21,22],"value":"{"},
1486
					{"type":"Identifier","range":[22,25],"value":"one"},
1487
					{"type":"Punctuator","range":[25,26],"value":":"},
1488
					{"type":"Punctuator","range":[26,27],"value":"{"},
1489
					{"type":"Identifier","range":[27,28],"value":"a"},
1490
					{"type":"Punctuator","range":[28,29],"value":"}"},
1491
					{"type":"Punctuator","range":[29,30],"value":"}"},
1492
					{"type":"Punctuator","range":[30,31],"value":";"},
1493
					{"type":"Punctuator","range":[31,32],"value":"}"}],
1494
			errors: [{"lineNumber":1,"index":27,"message":"Unexpected token a","token":"a"}]
1495
		},
1496
		
1497
		'obj prop ident recovery - return nested 2': {
1498
			source: 'function f() {return {one:{a b:1}};}',
1499
			nodes: [{"type":"FunctionDeclaration","range":[13,36]},
1500
					{"type":"Identifier","name":"f","range":[9,10]},
1501
					{"type":"BlockStatement","range":[14,36]},
1502
					{"type":"ReturnStatement","range":[20,35]},
1503
					{"type":"ObjectExpression","range":[22,34]},
1504
					{"type":"Property","kind":"init","range":[26,33]},
1505
					{"type":"Identifier","name":"one","range":[22,25]},
1506
					{"type":"ObjectExpression","range":[27,33]},
1507
					{"type":"Property","kind":"init","range":[30,32]},
1508
					{"type":"Identifier","name":"b","range":[30,30]},
1509
					{"type":"Literal","range":[31,32],"value":1}],
1510
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1511
					{"type":"Identifier","range":[9,10],"value":"f"},
1512
					{"type":"Punctuator","range":[10,11],"value":"("},
1513
					{"type":"Punctuator","range":[11,12],"value":")"},
1514
					{"type":"Punctuator","range":[13,14],"value":"{"},
1515
					{"type":"Keyword","range":[14,20],"value":"return"},
1516
					{"type":"Punctuator","range":[21,22],"value":"{"},
1517
					{"type":"Identifier","range":[22,25],"value":"one"},
1518
					{"type":"Punctuator","range":[25,26],"value":":"},
1519
					{"type":"Punctuator","range":[26,27],"value":"{"},
1520
					{"type":"Identifier","range":[27,28],"value":"a"},
1521
					{"type":"Identifier","range":[29,30],"value":"b"},
1522
					{"type":"Punctuator","range":[30,31],"value":":"},
1523
					{"type":"Numeric","range":[31,32],"value":"1"},
1524
					{"type":"Punctuator","range":[32,33],"value":"}"},
1525
					{"type":"Punctuator","range":[33,34],"value":"}"},
1526
					{"type":"Punctuator","range":[34,35],"value":";"},
1527
					{"type":"Punctuator","range":[35,36],"value":"}"}],
1528
			errors: [{"lineNumber":1,"index":27,"message":"Unexpected token a","token":"a"}]
1529
		},
1530
		
1531
		'obj prop ident recovery - return nested 3': {
1532
			source: 'function f() {return {one:{b:1, a c:2}};}',
1533
			nodes: [{"type":"FunctionDeclaration","range":[13,41]},
1534
					{"type":"Identifier","name":"f","range":[9,10]},
1535
					{"type":"BlockStatement","range":[14,41]},
1536
					{"type":"ReturnStatement","range":[20,40]},
1537
					{"type":"ObjectExpression","range":[22,39]},
1538
					{"type":"Property","kind":"init","range":[26,38]},
1539
					{"type":"Identifier","name":"one","range":[22,25]},
1540
					{"type":"ObjectExpression","range":[32,38]},
1541
					{"type":"Property","kind":"init","range":[27,30]},
1542
					{"type":"Identifier","name":"b","range":[27,28]},
1543
					{"type":"Literal","range":[29,30],"value":1},
1544
					{"type":"Property","kind":"init","range":[35,37]},
1545
					{"type":"Identifier","name":"c","range":[35,35]},
1546
					{"type":"Literal","range":[36,37],"value":2}],
1547
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1548
					{"type":"Identifier","range":[9,10],"value":"f"},
1549
					{"type":"Punctuator","range":[10,11],"value":"("},
1550
					{"type":"Punctuator","range":[11,12],"value":")"},
1551
					{"type":"Punctuator","range":[13,14],"value":"{"},
1552
					{"type":"Keyword","range":[14,20],"value":"return"},
1553
					{"type":"Punctuator","range":[21,22],"value":"{"},
1554
					{"type":"Identifier","range":[22,25],"value":"one"},
1555
					{"type":"Punctuator","range":[25,26],"value":":"},
1556
					{"type":"Punctuator","range":[26,27],"value":"{"},
1557
					{"type":"Identifier","range":[27,28],"value":"b"},
1558
					{"type":"Punctuator","range":[28,29],"value":":"},
1559
					{"type":"Numeric","range":[29,30],"value":"1"},
1560
					{"type":"Punctuator","range":[30,31],"value":","},
1561
					{"type":"Identifier","range":[32,33],"value":"a"},
1562
					{"type":"Identifier","range":[34,35],"value":"c"},
1563
					{"type":"Punctuator","range":[35,36],"value":":"},
1564
					{"type":"Numeric","range":[36,37],"value":"2"},
1565
					{"type":"Punctuator","range":[37,38],"value":"}"},
1566
					{"type":"Punctuator","range":[38,39],"value":"}"},
1567
					{"type":"Punctuator","range":[39,40],"value":";"},
1568
					{"type":"Punctuator","range":[40,41],"value":"}"}],
1569
			errors: [{"lineNumber":1,"index":32,"message":"Unexpected token a","token":"a"}]
1570
		},
1571
		
1572
		'obj prop ident recovery - return nested 4': {
1573
			source: 'function f() {return {one:{a b:1,c}};}',
1574
			nodes: [{"type":"FunctionDeclaration","range":[14,38]},
1575
					{"type":"Identifier","name":"f","range":[9,10]},
1576
					{"type":"BlockStatement","range":[20,38]},
1577
					{"type":"ReturnStatement","range":[20,37]},
1578
					{"type":"ObjectExpression","range":[26,36]},
1579
					{"type":"Property","kind":"init","range":[26,35]},
1580
					{"type":"Identifier","name":"one","range":[22,25]},
1581
					{"type":"ObjectExpression","range":[33,35]},
1582
					{"type":"Property","kind":"init","range":[30,32]},
1583
					{"type":"Identifier","name":"b","range":[30,30]},
1584
					{"type":"Literal","range":[31,32],"value":1}],
1585
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1586
					{"type":"Identifier","range":[9,10],"value":"f"},
1587
					{"type":"Punctuator","range":[10,11],"value":"("},
1588
					{"type":"Punctuator","range":[11,12],"value":")"},
1589
					{"type":"Punctuator","range":[13,14],"value":"{"},
1590
					{"type":"Keyword","range":[14,20],"value":"return"},
1591
					{"type":"Punctuator","range":[21,22],"value":"{"},
1592
					{"type":"Identifier","range":[22,25],"value":"one"},
1593
					{"type":"Punctuator","range":[25,26],"value":":"},
1594
					{"type":"Punctuator","range":[26,27],"value":"{"},
1595
					{"type":"Identifier","range":[27,28],"value":"a"},
1596
					{"type":"Identifier","range":[29,30],"value":"b"},
1597
					{"type":"Punctuator","range":[30,31],"value":":"},
1598
					{"type":"Numeric","range":[31,32],"value":"1"},
1599
					{"type":"Punctuator","range":[32,33],"value":","},
1600
					{"type":"Identifier","range":[33,34],"value":"c"},
1601
					{"type":"Punctuator","range":[34,35],"value":"}"},
1602
					{"type":"Punctuator","range":[35,36],"value":"}"},
1603
					{"type":"Punctuator","range":[36,37],"value":";"},
1604
					{"type":"Punctuator","range":[37,38],"value":"}"}],
1605
			errors: [{"lineNumber":1,"index":27,"message":"Unexpected token a","token":"a"},
1606
					{"lineNumber":1,"index":33,"message":"Unexpected token c","token":"c"}]
1607
		},
1608
		'obj prop ident recovery - return nested 5': {
1609
			source: 'function f() {return {two one:{a b:1,c}};}',
1610
			nodes: [{"type":"FunctionDeclaration","range":[20,42]},
1611
					{"type":"Identifier","name":"f","range":[9,10]},
1612
					{"type":"BlockStatement","range":[20,42]},
1613
					{"type":"ReturnStatement","range":[20,41]},
1614
					{"type":"ObjectExpression","range":[30,40]},
1615
					{"type":"Property","kind":"init","range":[30,39]},
1616
					{"type":"Identifier","name":"one","range":[29,29]},
1617
					{"type":"ObjectExpression","range":[37,39]},
1618
					{"type":"Property","kind":"init","range":[34,36]},
1619
					{"type":"Identifier","name":"b","range":[34,34]},
1620
					{"type":"Literal","range":[35,36],"value":1}],
1621
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1622
					{"type":"Identifier","range":[9,10],"value":"f"},
1623
					{"type":"Punctuator","range":[10,11],"value":"("},
1624
					{"type":"Punctuator","range":[11,12],"value":")"},
1625
					{"type":"Punctuator","range":[13,14],"value":"{"},
1626
					{"type":"Keyword","range":[14,20],"value":"return"},
1627
					{"type":"Punctuator","range":[21,22],"value":"{"},
1628
					{"type":"Identifier","range":[22,25],"value":"two"},
1629
					{"type":"Identifier","range":[26,29],"value":"one"},
1630
					{"type":"Punctuator","range":[29,30],"value":":"},
1631
					{"type":"Punctuator","range":[30,31],"value":"{"},
1632
					{"type":"Identifier","range":[31,32],"value":"a"},
1633
					{"type":"Identifier","range":[33,34],"value":"b"},
1634
					{"type":"Punctuator","range":[34,35],"value":":"},
1635
					{"type":"Numeric","range":[35,36],"value":"1"},
1636
					{"type":"Punctuator","range":[36,37],"value":","},
1637
					{"type":"Identifier","range":[37,38],"value":"c"},
1638
					{"type":"Punctuator","range":[38,39],"value":"}"},
1639
					{"type":"Punctuator","range":[39,40],"value":"}"},
1640
					{"type":"Punctuator","range":[40,41],"value":";"},
1641
					{"type":"Punctuator","range":[41,42],"value":"}"}],
1642
			errors: [{"lineNumber":1,"index":22,"message":"Unexpected token two","token":"two"},
1643
					{"lineNumber":1,"index":31,"message":"Unexpected token a","token":"a"},
1644
					{"lineNumber":1,"index":37,"message":"Unexpected token c","token":"c"}]
1645
		},
1646
		'obj prop ident recovery - return nested 6': {
1647
			source: 'function f() {return {two one:{a b:1,c}, three};}',
1648
			nodes: [{"type":"FunctionDeclaration","range":[20,49]},
1649
					{"type":"Identifier","name":"f","range":[9,10]},
1650
					{"type":"BlockStatement","range":[20,49]},
1651
					{"type":"ReturnStatement","range":[21,48]},
1652
					{"type":"ObjectExpression","range":[41,47]},
1653
					{"type":"Property","kind":"init","range":[30,39]},
1654
					{"type":"Identifier","name":"one","range":[29,29]},
1655
					{"type":"ObjectExpression","range":[37,39]},
1656
					{"type":"Property","kind":"init","range":[34,36]},
1657
					{"type":"Identifier","name":"b","range":[34,34]},
1658
					{"type":"Literal","range":[35,36],"value":1}],
1659
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1660
					{"type":"Identifier","range":[9,10],"value":"f"},
1661
					{"type":"Punctuator","range":[10,11],"value":"("},
1662
					{"type":"Punctuator","range":[11,12],"value":")"},
1663
					{"type":"Punctuator","range":[13,14],"value":"{"},
1664
					{"type":"Keyword","range":[14,20],"value":"return"},
1665
					{"type":"Punctuator","range":[21,22],"value":"{"},
1666
					{"type":"Identifier","range":[22,25],"value":"two"},
1667
					{"type":"Identifier","range":[26,29],"value":"one"},
1668
					{"type":"Punctuator","range":[29,30],"value":":"},
1669
					{"type":"Punctuator","range":[30,31],"value":"{"},
1670
					{"type":"Identifier","range":[31,32],"value":"a"},
1671
					{"type":"Identifier","range":[33,34],"value":"b"},
1672
					{"type":"Punctuator","range":[34,35],"value":":"},
1673
					{"type":"Numeric","range":[35,36],"value":"1"},
1674
					{"type":"Punctuator","range":[36,37],"value":","},
1675
					{"type":"Identifier","range":[37,38],"value":"c"},
1676
					{"type":"Punctuator","range":[38,39],"value":"}"},
1677
					{"type":"Punctuator","range":[39,40],"value":","},
1678
					{"type":"Identifier","range":[41,46],"value":"three"},
1679
					{"type":"Punctuator","range":[46,47],"value":"}"},
1680
					{"type":"Punctuator","range":[47,48],"value":";"},
1681
					{"type":"Punctuator","range":[48,49],"value":"}"}],
1682
			errors: [{"lineNumber":1,"index":22,"message":"Unexpected token two","token":"two"},
1683
					{"lineNumber":1,"index":31,"message":"Unexpected token a","token":"a"},
1684
					{"lineNumber":1,"index":37,"message":"Unexpected token c","token":"c"},
1685
					{"lineNumber":1,"index":41,"message":"Unexpected token three","token":"three"}]
1686
		},
1687
		
1688
		'obj prop ident recovery - multi 1': {
1689
			source: 'function f() {return {two one:{a b:1,c}, three};}var v = {d:1, a};',
1690
			nodes: [{"type":"FunctionDeclaration","range":[20,49]},
1691
					{"type":"Identifier","name":"f","range":[9,10]},
1692
					{"type":"BlockStatement","range":[20,49]},
1693
					{"type":"ReturnStatement","range":[21,48]},
1694
					{"type":"ObjectExpression","range":[41,47]},
1695
					{"type":"Property","kind":"init","range":[30,39]},
1696
					{"type":"Identifier","name":"one","range":[29,29]},
1697
					{"type":"ObjectExpression","range":[37,39]},
1698
					{"type":"Property","kind":"init","range":[34,36]},
1699
					{"type":"Identifier","name":"b","range":[34,34]},
1700
					{"type":"Literal","range":[35,36],"value":1},
1701
					{"type":"VariableDeclaration","kind":"var","range":[53,66]},
1702
					{"type":"VariableDeclarator","range":[56,65]},
1703
					{"type":"Identifier","name":"v","range":[53,54]},
1704
					{"type":"ObjectExpression","range":[63,65]},
1705
					{"type":"Property","kind":"init","range":[58,61]},
1706
					{"type":"Identifier","name":"d","range":[58,59]},
1707
					{"type":"Literal","range":[60,61],"value":1}],
1708
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1709
					{"type":"Identifier","range":[9,10],"value":"f"},
1710
					{"type":"Punctuator","range":[10,11],"value":"("},
1711
					{"type":"Punctuator","range":[11,12],"value":")"},
1712
					{"type":"Punctuator","range":[13,14],"value":"{"},
1713
					{"type":"Keyword","range":[14,20],"value":"return"},
1714
					{"type":"Punctuator","range":[21,22],"value":"{"},
1715
					{"type":"Identifier","range":[22,25],"value":"two"},
1716
					{"type":"Identifier","range":[26,29],"value":"one"},
1717
					{"type":"Punctuator","range":[29,30],"value":":"},
1718
					{"type":"Punctuator","range":[30,31],"value":"{"},
1719
					{"type":"Identifier","range":[31,32],"value":"a"},
1720
					{"type":"Identifier","range":[33,34],"value":"b"},
1721
					{"type":"Punctuator","range":[34,35],"value":":"},
1722
					{"type":"Numeric","range":[35,36],"value":"1"},
1723
					{"type":"Punctuator","range":[36,37],"value":","},
1724
					{"type":"Identifier","range":[37,38],"value":"c"},
1725
					{"type":"Punctuator","range":[38,39],"value":"}"},
1726
					{"type":"Punctuator","range":[39,40],"value":","},
1727
					{"type":"Identifier","range":[41,46],"value":"three"},
1728
					{"type":"Punctuator","range":[46,47],"value":"}"},
1729
					{"type":"Punctuator","range":[47,48],"value":";"},
1730
					{"type":"Punctuator","range":[48,49],"value":"}"},
1731
					{"type":"Keyword","range":[49,52],"value":"var"},
1732
					{"type":"Identifier","range":[53,54],"value":"v"},
1733
					{"type":"Punctuator","range":[55,56],"value":"="},
1734
					{"type":"Punctuator","range":[57,58],"value":"{"},
1735
					{"type":"Identifier","range":[58,59],"value":"d"},
1736
					{"type":"Punctuator","range":[59,60],"value":":"},
1737
					{"type":"Numeric","range":[60,61],"value":"1"},
1738
					{"type":"Punctuator","range":[61,62],"value":","},
1739
					{"type":"Identifier","range":[63,64],"value":"a"},
1740
					{"type":"Punctuator","range":[64,65],"value":"}"},
1741
					{"type":"Punctuator","range":[65,66],"value":";"}],
1742
			errors: [{"lineNumber":1,"index":22,"message":"Unexpected token two","token":"two"},
1743
					{"lineNumber":1,"index":31,"message":"Unexpected token a","token":"a"},
1744
					{"lineNumber":1,"index":37,"message":"Unexpected token c","token":"c"},
1745
					{"lineNumber":1,"index":41,"message":"Unexpected token three","token":"three"},
1746
					{"lineNumber":1,"index":63,"message":"Unexpected token a","token":"a"}]
1747
		},
1748
		
1749
		'obj prop ident recovery - multi 2': {
1750
			source: 'function f() {return {two one:{a b:1,c}, three};}var v = {d:1, a};f({aa bb:1, cc});',
1751
			nodes: [{"type":"FunctionDeclaration","range":[20,49]},
1752
					{"type":"Identifier","name":"f","range":[9,10]},
1753
					{"type":"BlockStatement","range":[20,49]},
1754
					{"type":"ReturnStatement","range":[21,48]},
1755
					{"type":"ObjectExpression","range":[41,47]},
1756
					{"type":"Property","kind":"init","range":[30,39]},
1757
					{"type":"Identifier","name":"one","range":[29,29]},
1758
					{"type":"ObjectExpression","range":[37,39]},
1759
					{"type":"Property","kind":"init","range":[34,36]},
1760
					{"type":"Identifier","name":"b","range":[34,34]},
1761
					{"type":"Literal","range":[35,36],"value":1},
1762
					{"type":"VariableDeclaration","kind":"var","range":[53,66]},
1763
					{"type":"VariableDeclarator","range":[56,65]},
1764
					{"type":"Identifier","name":"v","range":[53,54]},
1765
					{"type":"ObjectExpression","range":[63,65]},
1766
					{"type":"Property","kind":"init","range":[58,61]},
1767
					{"type":"Identifier","name":"d","range":[58,59]},
1768
					{"type":"Literal","range":[60,61],"value":1},
1769
					{"type":"ExpressionStatement","range":[66,83]},
1770
					{"type":"CallExpression","range":[66,82]},
1771
					{"type":"Identifier","name":"f","range":[66,67]},
1772
					{"type":"ObjectExpression","range":[78,81]},
1773
					{"type":"Property","kind":"init","range":[74,76]},
1774
					{"type":"Identifier","name":"bb","range":[74,74]},
1775
					{"type":"Literal","range":[75,76],"value":1}],
1776
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
1777
					{"type":"Identifier","range":[9,10],"value":"f"},
1778
					{"type":"Punctuator","range":[10,11],"value":"("},
1779
					{"type":"Punctuator","range":[11,12],"value":")"},
1780
					{"type":"Punctuator","range":[13,14],"value":"{"},
1781
					{"type":"Keyword","range":[14,20],"value":"return"},
1782
					{"type":"Punctuator","range":[21,22],"value":"{"},
1783
					{"type":"Identifier","range":[22,25],"value":"two"},
1784
					{"type":"Identifier","range":[26,29],"value":"one"},
1785
					{"type":"Punctuator","range":[29,30],"value":":"},
1786
					{"type":"Punctuator","range":[30,31],"value":"{"},
1787
					{"type":"Identifier","range":[31,32],"value":"a"},
1788
					{"type":"Identifier","range":[33,34],"value":"b"},
1789
					{"type":"Punctuator","range":[34,35],"value":":"},
1790
					{"type":"Numeric","range":[35,36],"value":"1"},
1791
					{"type":"Punctuator","range":[36,37],"value":","},
1792
					{"type":"Identifier","range":[37,38],"value":"c"},
1793
					{"type":"Punctuator","range":[38,39],"value":"}"},
1794
					{"type":"Punctuator","range":[39,40],"value":","},
1795
					{"type":"Identifier","range":[41,46],"value":"three"},
1796
					{"type":"Punctuator","range":[46,47],"value":"}"},
1797
					{"type":"Punctuator","range":[47,48],"value":";"},
1798
					{"type":"Punctuator","range":[48,49],"value":"}"},
1799
					{"type":"Keyword","range":[49,52],"value":"var"},
1800
					{"type":"Identifier","range":[53,54],"value":"v"},
1801
					{"type":"Punctuator","range":[55,56],"value":"="},
1802
					{"type":"Punctuator","range":[57,58],"value":"{"},
1803
					{"type":"Identifier","range":[58,59],"value":"d"},
1804
					{"type":"Punctuator","range":[59,60],"value":":"},
1805
					{"type":"Numeric","range":[60,61],"value":"1"},
1806
					{"type":"Punctuator","range":[61,62],"value":","},
1807
					{"type":"Identifier","range":[63,64],"value":"a"},
1808
					{"type":"Punctuator","range":[64,65],"value":"}"},
1809
					{"type":"Punctuator","range":[65,66],"value":";"},
1810
					{"type":"Identifier","range":[66,67],"value":"f"},
1811
					{"type":"Punctuator","range":[67,68],"value":"("},
1812
					{"type":"Punctuator","range":[68,69],"value":"{"},
1813
					{"type":"Identifier","range":[69,71],"value":"aa"},
1814
					{"type":"Identifier","range":[72,74],"value":"bb"},
1815
					{"type":"Punctuator","range":[74,75],"value":":"},
1816
					{"type":"Numeric","range":[75,76],"value":"1"},
1817
					{"type":"Punctuator","range":[76,77],"value":","},
1818
					{"type":"Identifier","range":[78,80],"value":"cc"},
1819
					{"type":"Punctuator","range":[80,81],"value":"}"},
1820
					{"type":"Punctuator","range":[81,82],"value":")"},
1821
					{"type":"Punctuator","range":[82,83],"value":";"}],
1822
			errors: [{"lineNumber":1,"index":22,"message":"Unexpected token two","token":"two"},
1823
					{"lineNumber":1,"index":31,"message":"Unexpected token a","token":"a"},
1824
					{"lineNumber":1,"index":37,"message":"Unexpected token c","token":"c"},
1825
					{"lineNumber":1,"index":41,"message":"Unexpected token three","token":"three"},
1826
					{"lineNumber":1,"index":63,"message":"Unexpected token a","token":"a"},
1827
					{"lineNumber":1,"index":69,"message":"Unexpected token aa","token":"aa"},
1828
					{"lineNumber":1,"index":78,"message":"Unexpected token cc","token":"cc"}]
1829
		},
1830
		
1831
		'obj prop recovery - missing comma 1': {
1832
			source: 'var f = {a:1 b:2};',
1833
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[0,18]},
1834
					{"type":"VariableDeclarator","range":[4,17]},
1835
					{"type":"Identifier","name":"f","range":[4,5]},
1836
					{"type":"ObjectExpression","range":[8,17]},
1837
					{"type":"Property","kind":"init","range":[9,12]},
1838
					{"type":"Identifier","name":"a","range":[9,10]},
1839
					{"type":"Literal","range":[11,12],"value":1},
1840
					{"type":"Property","kind":"init","range":[13,16]},
1841
					{"type":"Identifier","name":"b","range":[13,14]},
1842
					{"type":"Literal","range":[15,16],"value":2}],
1843
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
1844
					{"type":"Identifier","range":[4,5],"value":"f"},
1845
					{"type":"Punctuator","range":[6,7],"value":"="},
1846
					{"type":"Punctuator","range":[8,9],"value":"{"},
1847
					{"type":"Identifier","range":[9,10],"value":"a"},
1848
					{"type":"Punctuator","range":[10,11],"value":":"},
1849
					{"type":"Numeric","range":[11,12],"value":"1"},
1850
					{"type":"Identifier","range":[13,14],"value":"b"},
1851
					{"type":"Punctuator","range":[14,15],"value":":"},
1852
					{"type":"Numeric","range":[15,16],"value":"2"},
1853
					{"type":"Punctuator","range":[16,17],"value":"}"},
1854
					{"type":"Punctuator","range":[17,18],"value":";"}],
1855
			errors: [{"lineNumber":1,"index":12,"message":"Missing expected ','"}]
1856
		},
1857
		
1858
		'obj prop recovery - missing comma 2': {
1859
			source: 'var f = {a:1 b:2 c:3};',
1860
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[0,22]},
1861
					{"type":"VariableDeclarator","range":[4,21]},
1862
					{"type":"Identifier","name":"f","range":[4,5]},
1863
					{"type":"ObjectExpression","range":[8,21]},
1864
					{"type":"Property","kind":"init","range":[9,12]},
1865
					{"type":"Identifier","name":"a","range":[9,10]},
1866
					{"type":"Literal","range":[11,12],"value":1},
1867
					{"type":"Property","kind":"init","range":[13,16]},
1868
					{"type":"Identifier","name":"b","range":[13,14]},
1869
					{"type":"Literal","range":[15,16],"value":2},
1870
					{"type":"Property","kind":"init","range":[17,20]},
1871
					{"type":"Identifier","name":"c","range":[17,18]},
1872
					{"type":"Literal","range":[19,20],"value":3}],
1873
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
1874
					{"type":"Identifier","range":[4,5],"value":"f"},
1875
					{"type":"Punctuator","range":[6,7],"value":"="},
1876
					{"type":"Punctuator","range":[8,9],"value":"{"},
1877
					{"type":"Identifier","range":[9,10],"value":"a"},
1878
					{"type":"Punctuator","range":[10,11],"value":":"},
1879
					{"type":"Numeric","range":[11,12],"value":"1"},
1880
					{"type":"Identifier","range":[13,14],"value":"b"},
1881
					{"type":"Punctuator","range":[14,15],"value":":"},
1882
					{"type":"Numeric","range":[15,16],"value":"2"},
1883
					{"type":"Identifier","range":[17,18],"value":"c"},
1884
					{"type":"Punctuator","range":[18,19],"value":":"},
1885
					{"type":"Numeric","range":[19,20],"value":"3"},
1886
					{"type":"Punctuator","range":[20,21],"value":"}"},
1887
					{"type":"Punctuator","range":[21,22],"value":";"}],
1888
			errors: [{"lineNumber":1,"index":12,"message":"Missing expected ','"},
1889
					{"lineNumber":1,"index":16,"message":"Missing expected ','"}]
1890
		},
1891
		
1892
		'obj prop recovery - missing comma 3': {
1893
			source: 'var f = {a:1 b:{aa:1 bb:2}};',
1894
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[0,28]},
1895
					{"type":"VariableDeclarator","range":[4,27]},
1896
					{"type":"Identifier","name":"f","range":[4,5]},
1897
					{"type":"ObjectExpression","range":[8,27]},
1898
					{"type":"Property","kind":"init","range":[9,12]},
1899
					{"type":"Identifier","name":"a","range":[9,10]},
1900
					{"type":"Literal","range":[11,12],"value":1},
1901
					{"type":"Property","kind":"init","range":[13,26]},
1902
					{"type":"Identifier","name":"b","range":[13,14]},
1903
					{"type":"ObjectExpression","range":[15,26]},
1904
					{"type":"Property","kind":"init","range":[16,20]},
1905
					{"type":"Identifier","name":"aa","range":[16,18]},
1906
					{"type":"Literal","range":[19,20],"value":1},
1907
					{"type":"Property","kind":"init","range":[21,25]},
1908
					{"type":"Identifier","name":"bb","range":[21,23]},
1909
					{"type":"Literal","range":[24,25],"value":2}],
1910
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
1911
					{"type":"Identifier","range":[4,5],"value":"f"},
1912
					{"type":"Punctuator","range":[6,7],"value":"="},
1913
					{"type":"Punctuator","range":[8,9],"value":"{"},
1914
					{"type":"Identifier","range":[9,10],"value":"a"},
1915
					{"type":"Punctuator","range":[10,11],"value":":"},
1916
					{"type":"Numeric","range":[11,12],"value":"1"},
1917
					{"type":"Identifier","range":[13,14],"value":"b"},
1918
					{"type":"Punctuator","range":[14,15],"value":":"},
1919
					{"type":"Punctuator","range":[15,16],"value":"{"},
1920
					{"type":"Identifier","range":[16,18],"value":"aa"},
1921
					{"type":"Punctuator","range":[18,19],"value":":"},
1922
					{"type":"Numeric","range":[19,20],"value":"1"},
1923
					{"type":"Identifier","range":[21,23],"value":"bb"},
1924
					{"type":"Punctuator","range":[23,24],"value":":"},
1925
					{"type":"Numeric","range":[24,25],"value":"2"},
1926
					{"type":"Punctuator","range":[25,26],"value":"}"},
1927
					{"type":"Punctuator","range":[26,27],"value":"}"},
1928
					{"type":"Punctuator","range":[27,28],"value":";"}],
1929
			errors: [{"lineNumber":1,"index":12,"message":"Missing expected ','"},
1930
					{"lineNumber":1,"index":20,"message":"Missing expected ','"}]
1931
		},
1932
		
1933
		'obj prop recovery - missing comma 4': {
1934
			source: 'var f = {a:1, b:{aa:1 bb:2} c:4};',
1935
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[0,33]},
1936
					{"type":"VariableDeclarator","range":[4,32]},
1937
					{"type":"Identifier","name":"f","range":[4,5]},
1938
					{"type":"ObjectExpression","range":[8,32]},
1939
					{"type":"Property","kind":"init","range":[9,12]},
1940
					{"type":"Identifier","name":"a","range":[9,10]},
1941
					{"type":"Literal","range":[11,12],"value":1},
1942
					{"type":"Property","kind":"init","range":[14,27]},
1943
					{"type":"Identifier","name":"b","range":[14,15]},
1944
					{"type":"ObjectExpression","range":[16,27]},
1945
					{"type":"Property","kind":"init","range":[17,21]},
1946
					{"type":"Identifier","name":"aa","range":[17,19]},
1947
					{"type":"Literal","range":[20,21],"value":1},
1948
					{"type":"Property","kind":"init","range":[22,26]},
1949
					{"type":"Identifier","name":"bb","range":[22,24]},
1950
					{"type":"Literal","range":[25,26],"value":2},
1951
					{"type":"Property","kind":"init","range":[28,31]},
1952
					{"type":"Identifier","name":"c","range":[28,29]},
1953
					{"type":"Literal","range":[30,31],"value":4}],
1954
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
1955
					{"type":"Identifier","range":[4,5],"value":"f"},
1956
					{"type":"Punctuator","range":[6,7],"value":"="},
1957
					{"type":"Punctuator","range":[8,9],"value":"{"},
1958
					{"type":"Identifier","range":[9,10],"value":"a"},
1959
					{"type":"Punctuator","range":[10,11],"value":":"},
1960
					{"type":"Numeric","range":[11,12],"value":"1"},
1961
					{"type":"Punctuator","range":[12,13],"value":","},
1962
					{"type":"Identifier","range":[14,15],"value":"b"},
1963
					{"type":"Punctuator","range":[15,16],"value":":"},
1964
					{"type":"Punctuator","range":[16,17],"value":"{"},
1965
					{"type":"Identifier","range":[17,19],"value":"aa"},
1966
					{"type":"Punctuator","range":[19,20],"value":":"},
1967
					{"type":"Numeric","range":[20,21],"value":"1"},
1968
					{"type":"Identifier","range":[22,24],"value":"bb"},
1969
					{"type":"Punctuator","range":[24,25],"value":":"},
1970
					{"type":"Numeric","range":[25,26],"value":"2"},
1971
					{"type":"Punctuator","range":[26,27],"value":"}"},
1972
					{"type":"Identifier","range":[28,29],"value":"c"},
1973
					{"type":"Punctuator","range":[29,30],"value":":"},
1974
					{"type":"Numeric","range":[30,31],"value":"4"},
1975
					{"type":"Punctuator","range":[31,32],"value":"}"},
1976
					{"type":"Punctuator","range":[32,33],"value":";"}],
1977
			errors: [{"lineNumber":1,"index":21,"message":"Missing expected ','"},
1978
					{"lineNumber":1,"index":27,"message":"Missing expected ','"}]
1979
		},
1980
		
1981
		'obj prop recovery - missing comma 5': {
1982
			source: 'var f = {a:1, b:{aa:1, bb:2 cc:4} c:4};',
1983
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[0,39]},
1984
					{"type":"VariableDeclarator","range":[4,38]},
1985
					{"type":"Identifier","name":"f","range":[4,5]},
1986
					{"type":"ObjectExpression","range":[8,38]},
1987
					{"type":"Property","kind":"init","range":[9,12]},
1988
					{"type":"Identifier","name":"a","range":[9,10]},
1989
					{"type":"Literal","range":[11,12],"value":1},
1990
					{"type":"Property","kind":"init","range":[14,33]},
1991
					{"type":"Identifier","name":"b","range":[14,15]},
1992
					{"type":"ObjectExpression","range":[16,33]},
1993
					{"type":"Property","kind":"init","range":[17,21]},
1994
					{"type":"Identifier","name":"aa","range":[17,19]},
1995
					{"type":"Literal","range":[20,21],"value":1},
1996
					{"type":"Property","kind":"init","range":[23,27]},
1997
					{"type":"Identifier","name":"bb","range":[23,25]},
1998
					{"type":"Literal","range":[26,27],"value":2},
1999
					{"type":"Property","kind":"init","range":[28,32]},
2000
					{"type":"Identifier","name":"cc","range":[28,30]},
2001
					{"type":"Literal","range":[31,32],"value":4},
2002
					{"type":"Property","kind":"init","range":[34,37]},
2003
					{"type":"Identifier","name":"c","range":[34,35]},
2004
					{"type":"Literal","range":[36,37],"value":4}],
2005
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2006
					{"type":"Identifier","range":[4,5],"value":"f"},
2007
					{"type":"Punctuator","range":[6,7],"value":"="},
2008
					{"type":"Punctuator","range":[8,9],"value":"{"},
2009
					{"type":"Identifier","range":[9,10],"value":"a"},
2010
					{"type":"Punctuator","range":[10,11],"value":":"},
2011
					{"type":"Numeric","range":[11,12],"value":"1"},
2012
					{"type":"Punctuator","range":[12,13],"value":","},
2013
					{"type":"Identifier","range":[14,15],"value":"b"},
2014
					{"type":"Punctuator","range":[15,16],"value":":"},
2015
					{"type":"Punctuator","range":[16,17],"value":"{"},
2016
					{"type":"Identifier","range":[17,19],"value":"aa"},
2017
					{"type":"Punctuator","range":[19,20],"value":":"},
2018
					{"type":"Numeric","range":[20,21],"value":"1"},
2019
					{"type":"Punctuator","range":[21,22],"value":","},
2020
					{"type":"Identifier","range":[23,25],"value":"bb"},
2021
					{"type":"Punctuator","range":[25,26],"value":":"},
2022
					{"type":"Numeric","range":[26,27],"value":"2"},
2023
					{"type":"Identifier","range":[28,30],"value":"cc"},
2024
					{"type":"Punctuator","range":[30,31],"value":":"},
2025
					{"type":"Numeric","range":[31,32],"value":"4"},
2026
					{"type":"Punctuator","range":[32,33],"value":"}"},
2027
					{"type":"Identifier","range":[34,35],"value":"c"},
2028
					{"type":"Punctuator","range":[35,36],"value":":"},
2029
					{"type":"Numeric","range":[36,37],"value":"4"},
2030
					{"type":"Punctuator","range":[37,38],"value":"}"},
2031
					{"type":"Punctuator","range":[38,39],"value":";"}],
2032
			errors: [{"lineNumber":1,"index":27,"message":"Missing expected ','"},
2033
					{"lineNumber":1,"index":33,"message":"Missing expected ','"}]
2034
		},
2035
		
2036
		'obj prop recovery - missing comma 6': {
2037
			source: 'function f(){} f({a:1, b:{aa:1, bb:2 cc:4} c:4});',
2038
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
2039
					{"type":"Identifier","name":"f","range":[9,10]},
2040
					{"type":"BlockStatement","range":[12,14]},
2041
					{"type":"ExpressionStatement","range":[15,49]},
2042
					{"type":"CallExpression","range":[15,48]},
2043
					{"type":"Identifier","name":"f","range":[15,16]},
2044
					{"type":"ObjectExpression","range":[17,47]},
2045
					{"type":"Property","kind":"init","range":[18,21]},
2046
					{"type":"Identifier","name":"a","range":[18,19]},
2047
					{"type":"Literal","range":[20,21],"value":1},
2048
					{"type":"Property","kind":"init","range":[23,42]},
2049
					{"type":"Identifier","name":"b","range":[23,24]},
2050
					{"type":"ObjectExpression","range":[25,42]},
2051
					{"type":"Property","kind":"init","range":[26,30]},
2052
					{"type":"Identifier","name":"aa","range":[26,28]},
2053
					{"type":"Literal","range":[29,30],"value":1},
2054
					{"type":"Property","kind":"init","range":[32,36]},
2055
					{"type":"Identifier","name":"bb","range":[32,34]},
2056
					{"type":"Literal","range":[35,36],"value":2},
2057
					{"type":"Property","kind":"init","range":[37,41]},
2058
					{"type":"Identifier","name":"cc","range":[37,39]},
2059
					{"type":"Literal","range":[40,41],"value":4},
2060
					{"type":"Property","kind":"init","range":[43,46]},
2061
					{"type":"Identifier","name":"c","range":[43,44]},
2062
					{"type":"Literal","range":[45,46],"value":4}],
2063
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2064
					{"type":"Identifier","range":[9,10],"value":"f"},
2065
					{"type":"Punctuator","range":[10,11],"value":"("},
2066
					{"type":"Punctuator","range":[11,12],"value":")"},
2067
					{"type":"Punctuator","range":[12,13],"value":"{"},
2068
					{"type":"Punctuator","range":[13,14],"value":"}"},
2069
					{"type":"Identifier","range":[15,16],"value":"f"},
2070
					{"type":"Punctuator","range":[16,17],"value":"("},
2071
					{"type":"Punctuator","range":[17,18],"value":"{"},
2072
					{"type":"Identifier","range":[18,19],"value":"a"},
2073
					{"type":"Punctuator","range":[19,20],"value":":"},
2074
					{"type":"Numeric","range":[20,21],"value":"1"},
2075
					{"type":"Punctuator","range":[21,22],"value":","},
2076
					{"type":"Identifier","range":[23,24],"value":"b"},
2077
					{"type":"Punctuator","range":[24,25],"value":":"},
2078
					{"type":"Punctuator","range":[25,26],"value":"{"},
2079
					{"type":"Identifier","range":[26,28],"value":"aa"},
2080
					{"type":"Punctuator","range":[28,29],"value":":"},
2081
					{"type":"Numeric","range":[29,30],"value":"1"},
2082
					{"type":"Punctuator","range":[30,31],"value":","},
2083
					{"type":"Identifier","range":[32,34],"value":"bb"},
2084
					{"type":"Punctuator","range":[34,35],"value":":"},
2085
					{"type":"Numeric","range":[35,36],"value":"2"},
2086
					{"type":"Identifier","range":[37,39],"value":"cc"},
2087
					{"type":"Punctuator","range":[39,40],"value":":"},
2088
					{"type":"Numeric","range":[40,41],"value":"4"},
2089
					{"type":"Punctuator","range":[41,42],"value":"}"},
2090
					{"type":"Identifier","range":[43,44],"value":"c"},
2091
					{"type":"Punctuator","range":[44,45],"value":":"},
2092
					{"type":"Numeric","range":[45,46],"value":"4"},
2093
					{"type":"Punctuator","range":[46,47],"value":"}"},
2094
					{"type":"Punctuator","range":[47,48],"value":")"},
2095
					{"type":"Punctuator","range":[48,49],"value":";"}],
2096
			errors: [{"lineNumber":1,"index":36,"message":"Missing expected ','"},
2097
					{"lineNumber":1,"index":42,"message":"Missing expected ','"}]
2098
		},
2099
		
2100
		'obj prop recovery - missing comma 7': {
2101
			source: 'function f(){} f({a:1 b:2});',
2102
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
2103
					{"type":"Identifier","name":"f","range":[9,10]},
2104
					{"type":"BlockStatement","range":[12,14]},
2105
					{"type":"ExpressionStatement","range":[15,28]},
2106
					{"type":"CallExpression","range":[15,27]},
2107
					{"type":"Identifier","name":"f","range":[15,16]},
2108
					{"type":"ObjectExpression","range":[17,26]},
2109
					{"type":"Property","kind":"init","range":[18,21]},
2110
					{"type":"Identifier","name":"a","range":[18,19]},
2111
					{"type":"Literal","range":[20,21],"value":1},
2112
					{"type":"Property","kind":"init","range":[22,25]},
2113
					{"type":"Identifier","name":"b","range":[22,23]},
2114
					{"type":"Literal","range":[24,25],"value":2}],
2115
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2116
					{"type":"Identifier","range":[9,10],"value":"f"},
2117
					{"type":"Punctuator","range":[10,11],"value":"("},
2118
					{"type":"Punctuator","range":[11,12],"value":")"},
2119
					{"type":"Punctuator","range":[12,13],"value":"{"},
2120
					{"type":"Punctuator","range":[13,14],"value":"}"},
2121
					{"type":"Identifier","range":[15,16],"value":"f"},
2122
					{"type":"Punctuator","range":[16,17],"value":"("},
2123
					{"type":"Punctuator","range":[17,18],"value":"{"},
2124
					{"type":"Identifier","range":[18,19],"value":"a"},
2125
					{"type":"Punctuator","range":[19,20],"value":":"},
2126
					{"type":"Numeric","range":[20,21],"value":"1"},
2127
					{"type":"Identifier","range":[22,23],"value":"b"},
2128
					{"type":"Punctuator","range":[23,24],"value":":"},
2129
					{"type":"Numeric","range":[24,25],"value":"2"},
2130
					{"type":"Punctuator","range":[25,26],"value":"}"},
2131
					{"type":"Punctuator","range":[26,27],"value":")"},
2132
					{"type":"Punctuator","range":[27,28],"value":";"}],
2133
			errors: [{"lineNumber":1,"index":21,"message":"Missing expected ','"}]
2134
		},
2135
		
2136
		'obj prop recovery - missing comma 8': {
2137
			source: 'function f(){} f({a:1 b:{aa:1 bb:2}});',
2138
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
2139
					{"type":"Identifier","name":"f","range":[9,10]},
2140
					{"type":"BlockStatement","range":[12,14]},
2141
					{"type":"ExpressionStatement","range":[15,38]},
2142
					{"type":"CallExpression","range":[15,37]},
2143
					{"type":"Identifier","name":"f","range":[15,16]},
2144
					{"type":"ObjectExpression","range":[17,36]},
2145
					{"type":"Property","kind":"init","range":[18,21]},
2146
					{"type":"Identifier","name":"a","range":[18,19]},
2147
					{"type":"Literal","range":[20,21],"value":1},
2148
					{"type":"Property","kind":"init","range":[22,35]},
2149
					{"type":"Identifier","name":"b","range":[22,23]},
2150
					{"type":"ObjectExpression","range":[24,35]},
2151
					{"type":"Property","kind":"init","range":[25,29]},
2152
					{"type":"Identifier","name":"aa","range":[25,27]},
2153
					{"type":"Literal","range":[28,29],"value":1},
2154
					{"type":"Property","kind":"init","range":[30,34]},
2155
					{"type":"Identifier","name":"bb","range":[30,32]},
2156
					{"type":"Literal","range":[33,34],"value":2}],
2157
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2158
					{"type":"Identifier","range":[9,10],"value":"f"},
2159
					{"type":"Punctuator","range":[10,11],"value":"("},
2160
					{"type":"Punctuator","range":[11,12],"value":")"},
2161
					{"type":"Punctuator","range":[12,13],"value":"{"},
2162
					{"type":"Punctuator","range":[13,14],"value":"}"},
2163
					{"type":"Identifier","range":[15,16],"value":"f"},
2164
					{"type":"Punctuator","range":[16,17],"value":"("},
2165
					{"type":"Punctuator","range":[17,18],"value":"{"},
2166
					{"type":"Identifier","range":[18,19],"value":"a"},
2167
					{"type":"Punctuator","range":[19,20],"value":":"},
2168
					{"type":"Numeric","range":[20,21],"value":"1"},
2169
					{"type":"Identifier","range":[22,23],"value":"b"},
2170
					{"type":"Punctuator","range":[23,24],"value":":"},
2171
					{"type":"Punctuator","range":[24,25],"value":"{"},
2172
					{"type":"Identifier","range":[25,27],"value":"aa"},
2173
					{"type":"Punctuator","range":[27,28],"value":":"},
2174
					{"type":"Numeric","range":[28,29],"value":"1"},
2175
					{"type":"Identifier","range":[30,32],"value":"bb"},
2176
					{"type":"Punctuator","range":[32,33],"value":":"},
2177
					{"type":"Numeric","range":[33,34],"value":"2"},
2178
					{"type":"Punctuator","range":[34,35],"value":"}"},
2179
					{"type":"Punctuator","range":[35,36],"value":"}"},
2180
					{"type":"Punctuator","range":[36,37],"value":")"},
2181
					{"type":"Punctuator","range":[37,38],"value":";"}],
2182
			errors: [{"lineNumber":1,"index":21,"message":"Missing expected ','"},
2183
					{"lineNumber":1,"index":29,"message":"Missing expected ','"}]
2184
		},
2185
		
2186
		'obj prop recovery - missing comma 9': {
2187
			source: 'function f(){} f({a:1, b:{aa:1 bb:2} c:4});',
2188
			nodes: [{"type":"FunctionDeclaration","range":[0,14]},
2189
					{"type":"Identifier","name":"f","range":[9,10]},
2190
					{"type":"BlockStatement","range":[12,14]},
2191
					{"type":"ExpressionStatement","range":[15,43]},
2192
					{"type":"CallExpression","range":[15,42]},
2193
					{"type":"Identifier","name":"f","range":[15,16]},
2194
					{"type":"ObjectExpression","range":[17,41]},
2195
					{"type":"Property","kind":"init","range":[18,21]},
2196
					{"type":"Identifier","name":"a","range":[18,19]},
2197
					{"type":"Literal","range":[20,21],"value":1},
2198
					{"type":"Property","kind":"init","range":[23,36]},
2199
					{"type":"Identifier","name":"b","range":[23,24]},
2200
					{"type":"ObjectExpression","range":[25,36]},
2201
					{"type":"Property","kind":"init","range":[26,30]},
2202
					{"type":"Identifier","name":"aa","range":[26,28]},
2203
					{"type":"Literal","range":[29,30],"value":1},
2204
					{"type":"Property","kind":"init","range":[31,35]},
2205
					{"type":"Identifier","name":"bb","range":[31,33]},
2206
					{"type":"Literal","range":[34,35],"value":2},
2207
					{"type":"Property","kind":"init","range":[37,40]},
2208
					{"type":"Identifier","name":"c","range":[37,38]},
2209
					{"type":"Literal","range":[39,40],"value":4}],
2210
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2211
					{"type":"Identifier","range":[9,10],"value":"f"},
2212
					{"type":"Punctuator","range":[10,11],"value":"("},
2213
					{"type":"Punctuator","range":[11,12],"value":")"},
2214
					{"type":"Punctuator","range":[12,13],"value":"{"},
2215
					{"type":"Punctuator","range":[13,14],"value":"}"},
2216
					{"type":"Identifier","range":[15,16],"value":"f"},
2217
					{"type":"Punctuator","range":[16,17],"value":"("},
2218
					{"type":"Punctuator","range":[17,18],"value":"{"},
2219
					{"type":"Identifier","range":[18,19],"value":"a"},
2220
					{"type":"Punctuator","range":[19,20],"value":":"},
2221
					{"type":"Numeric","range":[20,21],"value":"1"},
2222
					{"type":"Punctuator","range":[21,22],"value":","},
2223
					{"type":"Identifier","range":[23,24],"value":"b"},
2224
					{"type":"Punctuator","range":[24,25],"value":":"},
2225
					{"type":"Punctuator","range":[25,26],"value":"{"},
2226
					{"type":"Identifier","range":[26,28],"value":"aa"},
2227
					{"type":"Punctuator","range":[28,29],"value":":"},
2228
					{"type":"Numeric","range":[29,30],"value":"1"},
2229
					{"type":"Identifier","range":[31,33],"value":"bb"},
2230
					{"type":"Punctuator","range":[33,34],"value":":"},
2231
					{"type":"Numeric","range":[34,35],"value":"2"},
2232
					{"type":"Punctuator","range":[35,36],"value":"}"},
2233
					{"type":"Identifier","range":[37,38],"value":"c"},
2234
					{"type":"Punctuator","range":[38,39],"value":":"},
2235
					{"type":"Numeric","range":[39,40],"value":"4"},
2236
					{"type":"Punctuator","range":[40,41],"value":"}"},
2237
					{"type":"Punctuator","range":[41,42],"value":")"},
2238
					{"type":"Punctuator","range":[42,43],"value":";"}],
2239
			errors: [{"lineNumber":1,"index":30,"message":"Missing expected ','"},
2240
					{"lineNumber":1,"index":36,"message":"Missing expected ','"}]
2241
		},
2242
		
2243
		'obj prop recovery - missing comma 10': {
2244
			source: 'function f(){return {a:1 b:2};}',
2245
			nodes: [{"type":"FunctionDeclaration","range":[0,31]},
2246
					{"type":"Identifier","name":"f","range":[9,10]},
2247
					{"type":"BlockStatement","range":[12,31]},
2248
					{"type":"ReturnStatement","range":[13,30]},
2249
					{"type":"ObjectExpression","range":[20,29]},
2250
					{"type":"Property","kind":"init","range":[21,24]},
2251
					{"type":"Identifier","name":"a","range":[21,22]},
2252
					{"type":"Literal","range":[23,24],"value":1},
2253
					{"type":"Property","kind":"init","range":[25,28]},
2254
					{"type":"Identifier","name":"b","range":[25,26]},
2255
					{"type":"Literal","range":[27,28],"value":2}],
2256
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2257
					{"type":"Identifier","range":[9,10],"value":"f"},
2258
					{"type":"Punctuator","range":[10,11],"value":"("},
2259
					{"type":"Punctuator","range":[11,12],"value":")"},
2260
					{"type":"Punctuator","range":[12,13],"value":"{"},
2261
					{"type":"Keyword","range":[13,19],"value":"return"},
2262
					{"type":"Punctuator","range":[20,21],"value":"{"},
2263
					{"type":"Identifier","range":[21,22],"value":"a"},
2264
					{"type":"Punctuator","range":[22,23],"value":":"},
2265
					{"type":"Numeric","range":[23,24],"value":"1"},
2266
					{"type":"Identifier","range":[25,26],"value":"b"},
2267
					{"type":"Punctuator","range":[26,27],"value":":"},
2268
					{"type":"Numeric","range":[27,28],"value":"2"},
2269
					{"type":"Punctuator","range":[28,29],"value":"}"},
2270
					{"type":"Punctuator","range":[29,30],"value":";"},
2271
					{"type":"Punctuator","range":[30,31],"value":"}"}],
2272
			errors: [{"lineNumber":1,"index":24,"message":"Missing expected ','"}]
2273
		},
2274
		
2275
		'obj prop recovery - missing comma 11': {
2276
			source: 'function f(){return {a:1 b:2 c:3};}',
2277
			nodes: [{"type":"FunctionDeclaration","range":[0,35]},
2278
					{"type":"Identifier","name":"f","range":[9,10]},
2279
					{"type":"BlockStatement","range":[12,35]},
2280
					{"type":"ReturnStatement","range":[13,34]},
2281
					{"type":"ObjectExpression","range":[20,33]},
2282
					{"type":"Property","kind":"init","range":[21,24]},
2283
					{"type":"Identifier","name":"a","range":[21,22]},
2284
					{"type":"Literal","range":[23,24],"value":1},
2285
					{"type":"Property","kind":"init","range":[25,28]},
2286
					{"type":"Identifier","name":"b","range":[25,26]},
2287
					{"type":"Literal","range":[27,28],"value":2},
2288
					{"type":"Property","kind":"init","range":[29,32]},
2289
					{"type":"Identifier","name":"c","range":[29,30]},
2290
					{"type":"Literal","range":[31,32],"value":3}],
2291
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2292
					{"type":"Identifier","range":[9,10],"value":"f"},
2293
					{"type":"Punctuator","range":[10,11],"value":"("},
2294
					{"type":"Punctuator","range":[11,12],"value":")"},
2295
					{"type":"Punctuator","range":[12,13],"value":"{"},
2296
					{"type":"Keyword","range":[13,19],"value":"return"},
2297
					{"type":"Punctuator","range":[20,21],"value":"{"},
2298
					{"type":"Identifier","range":[21,22],"value":"a"},
2299
					{"type":"Punctuator","range":[22,23],"value":":"},
2300
					{"type":"Numeric","range":[23,24],"value":"1"},
2301
					{"type":"Identifier","range":[25,26],"value":"b"},
2302
					{"type":"Punctuator","range":[26,27],"value":":"},
2303
					{"type":"Numeric","range":[27,28],"value":"2"},
2304
					{"type":"Identifier","range":[29,30],"value":"c"},
2305
					{"type":"Punctuator","range":[30,31],"value":":"},
2306
					{"type":"Numeric","range":[31,32],"value":"3"},
2307
					{"type":"Punctuator","range":[32,33],"value":"}"},
2308
					{"type":"Punctuator","range":[33,34],"value":";"},
2309
					{"type":"Punctuator","range":[34,35],"value":"}"}],
2310
			errors: [{"lineNumber":1,"index":24,"message":"Missing expected ','"},
2311
					{"lineNumber":1,"index":28,"message":"Missing expected ','"}]
2312
		},
2313
		
2314
		'obj prop recovery - missing comma 12': {
2315
			source: 'function f(){return {a:1 b:{aa:1 bb:2}};}',
2316
			nodes: [{"type":"FunctionDeclaration","range":[0,41]},
2317
					{"type":"Identifier","name":"f","range":[9,10]},
2318
					{"type":"BlockStatement","range":[12,41]},
2319
					{"type":"ReturnStatement","range":[13,40]},
2320
					{"type":"ObjectExpression","range":[20,39]},
2321
					{"type":"Property","kind":"init","range":[21,24]},
2322
					{"type":"Identifier","name":"a","range":[21,22]},
2323
					{"type":"Literal","range":[23,24],"value":1},
2324
					{"type":"Property","kind":"init","range":[25,38]},
2325
					{"type":"Identifier","name":"b","range":[25,26]},
2326
					{"type":"ObjectExpression","range":[27,38]},
2327
					{"type":"Property","kind":"init","range":[28,32]},
2328
					{"type":"Identifier","name":"aa","range":[28,30]},
2329
					{"type":"Literal","range":[31,32],"value":1},
2330
					{"type":"Property","kind":"init","range":[33,37]},
2331
					{"type":"Identifier","name":"bb","range":[33,35]},
2332
					{"type":"Literal","range":[36,37],"value":2}],
2333
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2334
					{"type":"Identifier","range":[9,10],"value":"f"},
2335
					{"type":"Punctuator","range":[10,11],"value":"("},
2336
					{"type":"Punctuator","range":[11,12],"value":")"},
2337
					{"type":"Punctuator","range":[12,13],"value":"{"},
2338
					{"type":"Keyword","range":[13,19],"value":"return"},
2339
					{"type":"Punctuator","range":[20,21],"value":"{"},
2340
					{"type":"Identifier","range":[21,22],"value":"a"},
2341
					{"type":"Punctuator","range":[22,23],"value":":"},
2342
					{"type":"Numeric","range":[23,24],"value":"1"},
2343
					{"type":"Identifier","range":[25,26],"value":"b"},
2344
					{"type":"Punctuator","range":[26,27],"value":":"},
2345
					{"type":"Punctuator","range":[27,28],"value":"{"},
2346
					{"type":"Identifier","range":[28,30],"value":"aa"},
2347
					{"type":"Punctuator","range":[30,31],"value":":"},
2348
					{"type":"Numeric","range":[31,32],"value":"1"},
2349
					{"type":"Identifier","range":[33,35],"value":"bb"},
2350
					{"type":"Punctuator","range":[35,36],"value":":"},
2351
					{"type":"Numeric","range":[36,37],"value":"2"},
2352
					{"type":"Punctuator","range":[37,38],"value":"}"},
2353
					{"type":"Punctuator","range":[38,39],"value":"}"},
2354
					{"type":"Punctuator","range":[39,40],"value":";"},
2355
					{"type":"Punctuator","range":[40,41],"value":"}"}],
2356
			errors: [{"lineNumber":1,"index":24,"message":"Missing expected ','"},
2357
					{"lineNumber":1,"index":32,"message":"Missing expected ','"}]
2358
		},
2359
		
2360
		'obj prop recovery - missing comma 13': {
2361
			source: 'function f(){return {a:1, b:{aa:1 bb:2} c:4};}',
2362
			nodes: [{"type":"FunctionDeclaration","range":[0,46]},
2363
					{"type":"Identifier","name":"f","range":[9,10]},
2364
					{"type":"BlockStatement","range":[12,46]},
2365
					{"type":"ReturnStatement","range":[13,45]},
2366
					{"type":"ObjectExpression","range":[20,44]},
2367
					{"type":"Property","kind":"init","range":[21,24]},
2368
					{"type":"Identifier","name":"a","range":[21,22]},
2369
					{"type":"Literal","range":[23,24],"value":1},
2370
					{"type":"Property","kind":"init","range":[26,39]},
2371
					{"type":"Identifier","name":"b","range":[26,27]},
2372
					{"type":"ObjectExpression","range":[28,39]},
2373
					{"type":"Property","kind":"init","range":[29,33]},
2374
					{"type":"Identifier","name":"aa","range":[29,31]},
2375
					{"type":"Literal","range":[32,33],"value":1},
2376
					{"type":"Property","kind":"init","range":[34,38]},
2377
					{"type":"Identifier","name":"bb","range":[34,36]},
2378
					{"type":"Literal","range":[37,38],"value":2},
2379
					{"type":"Property","kind":"init","range":[40,43]},
2380
					{"type":"Identifier","name":"c","range":[40,41]},
2381
					{"type":"Literal","range":[42,43],"value":4}],
2382
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2383
					{"type":"Identifier","range":[9,10],"value":"f"},
2384
					{"type":"Punctuator","range":[10,11],"value":"("},
2385
					{"type":"Punctuator","range":[11,12],"value":")"},
2386
					{"type":"Punctuator","range":[12,13],"value":"{"},
2387
					{"type":"Keyword","range":[13,19],"value":"return"},
2388
					{"type":"Punctuator","range":[20,21],"value":"{"},
2389
					{"type":"Identifier","range":[21,22],"value":"a"},
2390
					{"type":"Punctuator","range":[22,23],"value":":"},
2391
					{"type":"Numeric","range":[23,24],"value":"1"},
2392
					{"type":"Punctuator","range":[24,25],"value":","},
2393
					{"type":"Identifier","range":[26,27],"value":"b"},
2394
					{"type":"Punctuator","range":[27,28],"value":":"},
2395
					{"type":"Punctuator","range":[28,29],"value":"{"},
2396
					{"type":"Identifier","range":[29,31],"value":"aa"},
2397
					{"type":"Punctuator","range":[31,32],"value":":"},
2398
					{"type":"Numeric","range":[32,33],"value":"1"},
2399
					{"type":"Identifier","range":[34,36],"value":"bb"},
2400
					{"type":"Punctuator","range":[36,37],"value":":"},
2401
					{"type":"Numeric","range":[37,38],"value":"2"},
2402
					{"type":"Punctuator","range":[38,39],"value":"}"},
2403
					{"type":"Identifier","range":[40,41],"value":"c"},
2404
					{"type":"Punctuator","range":[41,42],"value":":"},
2405
					{"type":"Numeric","range":[42,43],"value":"4"},
2406
					{"type":"Punctuator","range":[43,44],"value":"}"},
2407
					{"type":"Punctuator","range":[44,45],"value":";"},
2408
					{"type":"Punctuator","range":[45,46],"value":"}"}],
2409
			errors: [{"lineNumber":1,"index":33,"message":"Missing expected ','"},
2410
					{"lineNumber":1,"index":39,"message":"Missing expected ','"}]
2411
		},
2412
		
2413
		'obj prop recovery - missing comma 14': {
2414
			source: 'function f(){return {a:1, b:{aa:1, bb:2 cc:4} c:4};',
2415
			nodes: [{"type":"FunctionDeclaration","range":[0,51]},
2416
					{"type":"Identifier","name":"f","range":[9,10]},
2417
					{"type":"BlockStatement","range":[12,51]},
2418
					{"type":"ReturnStatement","range":[13,51]},
2419
					{"type":"ObjectExpression","range":[20,50]},
2420
					{"type":"Property","kind":"init","range":[21,24]},
2421
					{"type":"Identifier","name":"a","range":[21,22]},
2422
					{"type":"Literal","range":[23,24],"value":1},
2423
					{"type":"Property","kind":"init","range":[26,45]},
2424
					{"type":"Identifier","name":"b","range":[26,27]},
2425
					{"type":"ObjectExpression","range":[28,45]},
2426
					{"type":"Property","kind":"init","range":[29,33]},
2427
					{"type":"Identifier","name":"aa","range":[29,31]},
2428
					{"type":"Literal","range":[32,33],"value":1},
2429
					{"type":"Property","kind":"init","range":[35,39]},
2430
					{"type":"Identifier","name":"bb","range":[35,37]},
2431
					{"type":"Literal","range":[38,39],"value":2},
2432
					{"type":"Property","kind":"init","range":[40,44]},
2433
					{"type":"Identifier","name":"cc","range":[40,42]},
2434
					{"type":"Literal","range":[43,44],"value":4},
2435
					{"type":"Property","kind":"init","range":[46,49]},
2436
					{"type":"Identifier","name":"c","range":[46,47]},
2437
					{"type":"Literal","range":[48,49],"value":4}],
2438
			tokens: [{"type":"Keyword","range":[0,8],"value":"function"},
2439
					{"type":"Identifier","range":[9,10],"value":"f"},
2440
					{"type":"Punctuator","range":[10,11],"value":"("},
2441
					{"type":"Punctuator","range":[11,12],"value":")"},
2442
					{"type":"Punctuator","range":[12,13],"value":"{"},
2443
					{"type":"Keyword","range":[13,19],"value":"return"},
2444
					{"type":"Punctuator","range":[20,21],"value":"{"},
2445
					{"type":"Identifier","range":[21,22],"value":"a"},
2446
					{"type":"Punctuator","range":[22,23],"value":":"},
2447
					{"type":"Numeric","range":[23,24],"value":"1"},
2448
					{"type":"Punctuator","range":[24,25],"value":","},
2449
					{"type":"Identifier","range":[26,27],"value":"b"},
2450
					{"type":"Punctuator","range":[27,28],"value":":"},
2451
					{"type":"Punctuator","range":[28,29],"value":"{"},
2452
					{"type":"Identifier","range":[29,31],"value":"aa"},
2453
					{"type":"Punctuator","range":[31,32],"value":":"},
2454
					{"type":"Numeric","range":[32,33],"value":"1"},
2455
					{"type":"Punctuator","range":[33,34],"value":","},
2456
					{"type":"Identifier","range":[35,37],"value":"bb"},
2457
					{"type":"Punctuator","range":[37,38],"value":":"},
2458
					{"type":"Numeric","range":[38,39],"value":"2"},
2459
					{"type":"Identifier","range":[40,42],"value":"cc"},
2460
					{"type":"Punctuator","range":[42,43],"value":":"},
2461
					{"type":"Numeric","range":[43,44],"value":"4"},
2462
					{"type":"Punctuator","range":[44,45],"value":"}"},
2463
					{"type":"Identifier","range":[46,47],"value":"c"},
2464
					{"type":"Punctuator","range":[47,48],"value":":"},
2465
					{"type":"Numeric","range":[48,49],"value":"4"},
2466
					{"type":"Punctuator","range":[49,50],"value":"}"},
2467
					{"type":"Punctuator","range":[50,51],"value":";"}],
2468
			errors: [{"lineNumber":1,"index":39,"message":"Missing expected ','"},
2469
					{"lineNumber":1,"index":45,"message":"Missing expected ','"},
2470
					{"lineNumber":1,"index":51,"message":"Unexpected end of input"}]
2471
		},
2472
		
2473
		'obj prop recovery - mixed 1': {
2474
			source: 'var v = {a b:1 c:2};',
2475
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,20]},
2476
					{"type":"VariableDeclarator","range":[7,19]},
2477
					{"type":"Identifier","name":"v","range":[4,5]},
2478
					{"type":"ObjectExpression","range":[9,19]},
2479
					{"type":"Property","kind":"init","range":[12,14]},
2480
					{"type":"Identifier","name":"b","range":[12,12]},
2481
					{"type":"Literal","range":[13,14],"value":1},
2482
					{"type":"Property","kind":"init","range":[15,18]},
2483
					{"type":"Identifier","name":"c","range":[15,16]},
2484
					{"type":"Literal","range":[17,18],"value":2}],
2485
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2486
					{"type":"Identifier","range":[4,5],"value":"v"},
2487
					{"type":"Punctuator","range":[6,7],"value":"="},
2488
					{"type":"Punctuator","range":[8,9],"value":"{"},
2489
					{"type":"Identifier","range":[9,10],"value":"a"},
2490
					{"type":"Identifier","range":[11,12],"value":"b"},
2491
					{"type":"Punctuator","range":[12,13],"value":":"},
2492
					{"type":"Numeric","range":[13,14],"value":"1"},
2493
					{"type":"Identifier","range":[15,16],"value":"c"},
2494
					{"type":"Punctuator","range":[16,17],"value":":"},
2495
					{"type":"Numeric","range":[17,18],"value":"2"},
2496
					{"type":"Punctuator","range":[18,19],"value":"}"},
2497
					{"type":"Punctuator","range":[19,20],"value":";"}],
2498
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
2499
					{"lineNumber":1,"index":14,"message":"Missing expected ','"}]
2500
		},
2501
		
2502
		'obj prop recovery - mixed 2': {
2503
			source: 'var v = {a b:1 d c:2};',
2504
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,22]},
2505
					{"type":"VariableDeclarator","range":[7,21]},
2506
					{"type":"Identifier","name":"v","range":[4,5]},
2507
					{"type":"ObjectExpression","range":[15,21]},
2508
					{"type":"Property","kind":"init","range":[12,14]},
2509
					{"type":"Identifier","name":"b","range":[12,12]},
2510
					{"type":"Literal","range":[13,14],"value":1},
2511
					{"type":"Property","kind":"init","range":[18,20]},
2512
					{"type":"Identifier","name":"c","range":[18,18]},
2513
					{"type":"Literal","range":[19,20],"value":2}],
2514
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2515
					{"type":"Identifier","range":[4,5],"value":"v"},
2516
					{"type":"Punctuator","range":[6,7],"value":"="},
2517
					{"type":"Punctuator","range":[8,9],"value":"{"},
2518
					{"type":"Identifier","range":[9,10],"value":"a"},
2519
					{"type":"Identifier","range":[11,12],"value":"b"},
2520
					{"type":"Punctuator","range":[12,13],"value":":"},
2521
					{"type":"Numeric","range":[13,14],"value":"1"},
2522
					{"type":"Identifier","range":[15,16],"value":"d"},
2523
					{"type":"Identifier","range":[17,18],"value":"c"},
2524
					{"type":"Punctuator","range":[18,19],"value":":"},
2525
					{"type":"Numeric","range":[19,20],"value":"2"},
2526
					{"type":"Punctuator","range":[20,21],"value":"}"},
2527
					{"type":"Punctuator","range":[21,22],"value":";"}],
2528
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
2529
					{"lineNumber":1,"index":14,"message":"Missing expected ','"},
2530
					{"lineNumber":1,"index":15,"message":"Unexpected token d","token":"d"}]
2531
		},
2532
		
2533
		'obj prop recovery - mixed 3': {
2534
			source: 'var v = {a b:{cc:3, dd:\'hey\' e} c:2};',
2535
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,37]},
2536
					{"type":"VariableDeclarator","range":[7,36]},
2537
					{"type":"Identifier","name":"v","range":[4,5]},
2538
					{"type":"ObjectExpression","range":[12,36]},
2539
					{"type":"Property","kind":"init","range":[13,31]},
2540
					{"type":"Identifier","name":"b","range":[12,12]},
2541
					{"type":"ObjectExpression","range":[29,31]},
2542
					{"type":"Property","kind":"init","range":[14,18]},
2543
					{"type":"Identifier","name":"cc","range":[14,16]},
2544
					{"type":"Literal","range":[17,18],"value":3},
2545
					{"type":"Property","kind":"init","range":[20,28]},
2546
					{"type":"Identifier","name":"dd","range":[20,22]},
2547
					{"type":"Literal","range":[23,28],"value":"hey"},
2548
					{"type":"Property","kind":"init","range":[32,35]},
2549
					{"type":"Identifier","name":"c","range":[32,33]},
2550
					{"type":"Literal","range":[34,35],"value":2}],
2551
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2552
					{"type":"Identifier","range":[4,5],"value":"v"},
2553
					{"type":"Punctuator","range":[6,7],"value":"="},
2554
					{"type":"Punctuator","range":[8,9],"value":"{"},
2555
					{"type":"Identifier","range":[9,10],"value":"a"},
2556
					{"type":"Identifier","range":[11,12],"value":"b"},
2557
					{"type":"Punctuator","range":[12,13],"value":":"},
2558
					{"type":"Punctuator","range":[13,14],"value":"{"},
2559
					{"type":"Identifier","range":[14,16],"value":"cc"},
2560
					{"type":"Punctuator","range":[16,17],"value":":"},
2561
					{"type":"Numeric","range":[17,18],"value":"3"},
2562
					{"type":"Punctuator","range":[18,19],"value":","},
2563
					{"type":"Identifier","range":[20,22],"value":"dd"},
2564
					{"type":"Punctuator","range":[22,23],"value":":"},
2565
					{"type":"String","range":[23,28],"value":"'hey'"},
2566
					{"type":"Identifier","range":[29,30],"value":"e"},
2567
					{"type":"Punctuator","range":[30,31],"value":"}"},
2568
					{"type":"Identifier","range":[32,33],"value":"c"},
2569
					{"type":"Punctuator","range":[33,34],"value":":"},
2570
					{"type":"Numeric","range":[34,35],"value":"2"},
2571
					{"type":"Punctuator","range":[35,36],"value":"}"},
2572
					{"type":"Punctuator","range":[36,37],"value":";"}],
2573
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
2574
					{"lineNumber":1,"index":28,"message":"Missing expected ','"},
2575
					{"lineNumber":1,"index":29,"message":"Unexpected token e","token":"e"},
2576
					{"lineNumber":1,"index":31,"message":"Missing expected ','"}]
2577
		},
2578
		
2579
		'obj prop recovery - mixed 4': {
2580
			source: 'var v = {a b:{cc:3, dd:\'hey\' e} c:2};function f() {return {a b:{cc:3, dd:\'hey\' e} c:2};}',
2581
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,37]},
2582
					{"type":"VariableDeclarator","range":[7,36]},
2583
					{"type":"Identifier","name":"v","range":[4,5]},
2584
					{"type":"ObjectExpression","range":[12,36]},
2585
					{"type":"Property","kind":"init","range":[13,31]},
2586
					{"type":"Identifier","name":"b","range":[12,12]},
2587
					{"type":"ObjectExpression","range":[29,31]},
2588
					{"type":"Property","kind":"init","range":[14,18]},
2589
					{"type":"Identifier","name":"cc","range":[14,16]},
2590
					{"type":"Literal","range":[17,18],"value":3},
2591
					{"type":"Property","kind":"init","range":[20,28]},
2592
					{"type":"Identifier","name":"dd","range":[20,22]},
2593
					{"type":"Literal","range":[23,28],"value":"hey"},
2594
					{"type":"Property","kind":"init","range":[32,35]},
2595
					{"type":"Identifier","name":"c","range":[32,33]},
2596
					{"type":"Literal","range":[34,35],"value":2},
2597
					{"type":"FunctionDeclaration","range":[51,88]},
2598
					{"type":"Identifier","name":"f","range":[46,47]},
2599
					{"type":"BlockStatement","range":[57,88]},
2600
					{"type":"ReturnStatement","range":[57,87]},
2601
					{"type":"ObjectExpression","range":[62,86]},
2602
					{"type":"Property","kind":"init","range":[63,81]},
2603
					{"type":"Identifier","name":"b","range":[62,62]},
2604
					{"type":"ObjectExpression","range":[79,81]},
2605
					{"type":"Property","kind":"init","range":[64,68]},
2606
					{"type":"Identifier","name":"cc","range":[64,66]},
2607
					{"type":"Literal","range":[67,68],"value":3},
2608
					{"type":"Property","kind":"init","range":[70,78]},
2609
					{"type":"Identifier","name":"dd","range":[70,72]},
2610
					{"type":"Literal","range":[73,78],"value":"hey"},
2611
					{"type":"Property","kind":"init","range":[82,85]},
2612
					{"type":"Identifier","name":"c","range":[82,83]},
2613
					{"type":"Literal","range":[84,85],"value":2}],
2614
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2615
					{"type":"Identifier","range":[4,5],"value":"v"},
2616
					{"type":"Punctuator","range":[6,7],"value":"="},
2617
					{"type":"Punctuator","range":[8,9],"value":"{"},
2618
					{"type":"Identifier","range":[9,10],"value":"a"},
2619
					{"type":"Identifier","range":[11,12],"value":"b"},
2620
					{"type":"Punctuator","range":[12,13],"value":":"},
2621
					{"type":"Punctuator","range":[13,14],"value":"{"},
2622
					{"type":"Identifier","range":[14,16],"value":"cc"},
2623
					{"type":"Punctuator","range":[16,17],"value":":"},
2624
					{"type":"Numeric","range":[17,18],"value":"3"},
2625
					{"type":"Punctuator","range":[18,19],"value":","},
2626
					{"type":"Identifier","range":[20,22],"value":"dd"},
2627
					{"type":"Punctuator","range":[22,23],"value":":"},
2628
					{"type":"String","range":[23,28],"value":"'hey'"},
2629
					{"type":"Identifier","range":[29,30],"value":"e"},
2630
					{"type":"Punctuator","range":[30,31],"value":"}"},
2631
					{"type":"Identifier","range":[32,33],"value":"c"},
2632
					{"type":"Punctuator","range":[33,34],"value":":"},
2633
					{"type":"Numeric","range":[34,35],"value":"2"},
2634
					{"type":"Punctuator","range":[35,36],"value":"}"},
2635
					{"type":"Punctuator","range":[36,37],"value":";"},
2636
					{"type":"Keyword","range":[37,45],"value":"function"},
2637
					{"type":"Identifier","range":[46,47],"value":"f"},
2638
					{"type":"Punctuator","range":[47,48],"value":"("},
2639
					{"type":"Punctuator","range":[48,49],"value":")"},
2640
					{"type":"Punctuator","range":[50,51],"value":"{"},
2641
					{"type":"Keyword","range":[51,57],"value":"return"},
2642
					{"type":"Punctuator","range":[58,59],"value":"{"},
2643
					{"type":"Identifier","range":[59,60],"value":"a"},
2644
					{"type":"Identifier","range":[61,62],"value":"b"},
2645
					{"type":"Punctuator","range":[62,63],"value":":"},
2646
					{"type":"Punctuator","range":[63,64],"value":"{"},
2647
					{"type":"Identifier","range":[64,66],"value":"cc"},
2648
					{"type":"Punctuator","range":[66,67],"value":":"},
2649
					{"type":"Numeric","range":[67,68],"value":"3"},
2650
					{"type":"Punctuator","range":[68,69],"value":","},
2651
					{"type":"Identifier","range":[70,72],"value":"dd"},
2652
					{"type":"Punctuator","range":[72,73],"value":":"},
2653
					{"type":"String","range":[73,78],"value":"'hey'"},
2654
					{"type":"Identifier","range":[79,80],"value":"e"},
2655
					{"type":"Punctuator","range":[80,81],"value":"}"},
2656
					{"type":"Identifier","range":[82,83],"value":"c"},
2657
					{"type":"Punctuator","range":[83,84],"value":":"},
2658
					{"type":"Numeric","range":[84,85],"value":"2"},
2659
					{"type":"Punctuator","range":[85,86],"value":"}"},
2660
					{"type":"Punctuator","range":[86,87],"value":";"},
2661
					{"type":"Punctuator","range":[87,88],"value":"}"}],
2662
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
2663
					{"lineNumber":1,"index":28,"message":"Missing expected ','"},
2664
					{"lineNumber":1,"index":29,"message":"Unexpected token e","token":"e"},
2665
					{"lineNumber":1,"index":31,"message":"Missing expected ','"},
2666
					{"lineNumber":1,"index":59,"message":"Unexpected token a","token":"a"},
2667
					{"lineNumber":1,"index":78,"message":"Missing expected ','"},
2668
					{"lineNumber":1,"index":79,"message":"Unexpected token e","token":"e"},
2669
					{"lineNumber":1,"index":81,"message":"Missing expected ','"}]
2670
		},
2671
		
2672
		'obj prop recovery - mixed 5': {
2673
			source: 'var v = {a b:1 c:2};function f() {return {a b:1 c:2};}',
2674
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,20]},
2675
					{"type":"VariableDeclarator","range":[7,19]},
2676
					{"type":"Identifier","name":"v","range":[4,5]},
2677
					{"type":"ObjectExpression","range":[9,19]},
2678
					{"type":"Property","kind":"init","range":[12,14]},
2679
					{"type":"Identifier","name":"b","range":[12,12]},
2680
					{"type":"Literal","range":[13,14],"value":1},
2681
					{"type":"Property","kind":"init","range":[15,18]},
2682
					{"type":"Identifier","name":"c","range":[15,16]},
2683
					{"type":"Literal","range":[17,18],"value":2},
2684
					{"type":"FunctionDeclaration","range":[33,54]},
2685
					{"type":"Identifier","name":"f","range":[29,30]},
2686
					{"type":"BlockStatement","range":[34,54]},
2687
					{"type":"ReturnStatement","range":[40,53]},
2688
					{"type":"ObjectExpression","range":[42,52]},
2689
					{"type":"Property","kind":"init","range":[45,47]},
2690
					{"type":"Identifier","name":"b","range":[45,45]},
2691
					{"type":"Literal","range":[46,47],"value":1},
2692
					{"type":"Property","kind":"init","range":[48,51]},
2693
					{"type":"Identifier","name":"c","range":[48,49]},
2694
					{"type":"Literal","range":[50,51],"value":2}],
2695
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2696
					{"type":"Identifier","range":[4,5],"value":"v"},
2697
					{"type":"Punctuator","range":[6,7],"value":"="},
2698
					{"type":"Punctuator","range":[8,9],"value":"{"},
2699
					{"type":"Identifier","range":[9,10],"value":"a"},
2700
					{"type":"Identifier","range":[11,12],"value":"b"},
2701
					{"type":"Punctuator","range":[12,13],"value":":"},
2702
					{"type":"Numeric","range":[13,14],"value":"1"},
2703
					{"type":"Identifier","range":[15,16],"value":"c"},
2704
					{"type":"Punctuator","range":[16,17],"value":":"},
2705
					{"type":"Numeric","range":[17,18],"value":"2"},
2706
					{"type":"Punctuator","range":[18,19],"value":"}"},
2707
					{"type":"Punctuator","range":[19,20],"value":";"},
2708
					{"type":"Keyword","range":[20,28],"value":"function"},
2709
					{"type":"Identifier","range":[29,30],"value":"f"},
2710
					{"type":"Punctuator","range":[30,31],"value":"("},
2711
					{"type":"Punctuator","range":[31,32],"value":")"},
2712
					{"type":"Punctuator","range":[33,34],"value":"{"},
2713
					{"type":"Keyword","range":[34,40],"value":"return"},
2714
					{"type":"Punctuator","range":[41,42],"value":"{"},
2715
					{"type":"Identifier","range":[42,43],"value":"a"},
2716
					{"type":"Identifier","range":[44,45],"value":"b"},
2717
					{"type":"Punctuator","range":[45,46],"value":":"},
2718
					{"type":"Numeric","range":[46,47],"value":"1"},
2719
					{"type":"Identifier","range":[48,49],"value":"c"},
2720
					{"type":"Punctuator","range":[49,50],"value":":"},
2721
					{"type":"Numeric","range":[50,51],"value":"2"},
2722
					{"type":"Punctuator","range":[51,52],"value":"}"},
2723
					{"type":"Punctuator","range":[52,53],"value":";"},
2724
					{"type":"Punctuator","range":[53,54],"value":"}"}],
2725
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
2726
					{"lineNumber":1,"index":14,"message":"Missing expected ','"},
2727
					{"lineNumber":1,"index":42,"message":"Unexpected token a","token":"a"},
2728
					{"lineNumber":1,"index":47,"message":"Missing expected ','"}]
2729
		},
2730
		
2731
		'obj prop recovery - mixed 6': {
2732
			source: 'var v = {a b:1 d c:2};function f() {return {a b:1 d c:2};}',
2733
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,22]},
2734
					{"type":"VariableDeclarator","range":[7,21]},
2735
					{"type":"Identifier","name":"v","range":[4,5]},
2736
					{"type":"ObjectExpression","range":[15,21]},
2737
					{"type":"Property","kind":"init","range":[12,14]},
2738
					{"type":"Identifier","name":"b","range":[12,12]},
2739
					{"type":"Literal","range":[13,14],"value":1},
2740
					{"type":"Property","kind":"init","range":[18,20]},
2741
					{"type":"Identifier","name":"c","range":[18,18]},
2742
					{"type":"Literal","range":[19,20],"value":2},
2743
					{"type":"FunctionDeclaration","range":[36,58]},
2744
					{"type":"Identifier","name":"f","range":[31,32]},
2745
					{"type":"BlockStatement","range":[42,58]},
2746
					{"type":"ReturnStatement","range":[42,57]},
2747
					{"type":"ObjectExpression","range":[50,56]},
2748
					{"type":"Property","kind":"init","range":[47,49]},
2749
					{"type":"Identifier","name":"b","range":[47,47]},
2750
					{"type":"Literal","range":[48,49],"value":1},
2751
					{"type":"Property","kind":"init","range":[53,55]},
2752
					{"type":"Identifier","name":"c","range":[53,53]},
2753
					{"type":"Literal","range":[54,55],"value":2}],
2754
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2755
					{"type":"Identifier","range":[4,5],"value":"v"},
2756
					{"type":"Punctuator","range":[6,7],"value":"="},
2757
					{"type":"Punctuator","range":[8,9],"value":"{"},
2758
					{"type":"Identifier","range":[9,10],"value":"a"},
2759
					{"type":"Identifier","range":[11,12],"value":"b"},
2760
					{"type":"Punctuator","range":[12,13],"value":":"},
2761
					{"type":"Numeric","range":[13,14],"value":"1"},
2762
					{"type":"Identifier","range":[15,16],"value":"d"},
2763
					{"type":"Identifier","range":[17,18],"value":"c"},
2764
					{"type":"Punctuator","range":[18,19],"value":":"},
2765
					{"type":"Numeric","range":[19,20],"value":"2"},
2766
					{"type":"Punctuator","range":[20,21],"value":"}"},
2767
					{"type":"Punctuator","range":[21,22],"value":";"},
2768
					{"type":"Keyword","range":[22,30],"value":"function"},
2769
					{"type":"Identifier","range":[31,32],"value":"f"},
2770
					{"type":"Punctuator","range":[32,33],"value":"("},
2771
					{"type":"Punctuator","range":[33,34],"value":")"},
2772
					{"type":"Punctuator","range":[35,36],"value":"{"},
2773
					{"type":"Keyword","range":[36,42],"value":"return"},
2774
					{"type":"Punctuator","range":[43,44],"value":"{"},
2775
					{"type":"Identifier","range":[44,45],"value":"a"},
2776
					{"type":"Identifier","range":[46,47],"value":"b"},
2777
					{"type":"Punctuator","range":[47,48],"value":":"},
2778
					{"type":"Numeric","range":[48,49],"value":"1"},
2779
					{"type":"Identifier","range":[50,51],"value":"d"},
2780
					{"type":"Identifier","range":[52,53],"value":"c"},
2781
					{"type":"Punctuator","range":[53,54],"value":":"},
2782
					{"type":"Numeric","range":[54,55],"value":"2"},
2783
					{"type":"Punctuator","range":[55,56],"value":"}"},
2784
					{"type":"Punctuator","range":[56,57],"value":";"},
2785
					{"type":"Punctuator","range":[57,58],"value":"}"}],
2786
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
2787
					{"lineNumber":1,"index":14,"message":"Missing expected ','"},
2788
					{"lineNumber":1,"index":15,"message":"Unexpected token d","token":"d"},
2789
					{"lineNumber":1,"index":44,"message":"Unexpected token a","token":"a"},
2790
					{"lineNumber":1,"index":49,"message":"Missing expected ','"},
2791
					{"lineNumber":1,"index":50,"message":"Unexpected token d","token":"d"}]
2792
		},
2793
		
2794
		'obj prop recovery - mixed 7': {
2795
			source: 'var v = {a b:1 c:2};function f() {return {a b:1 c:2};}f({a b:1 c:2});',
2796
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[4,20]},
2797
					{"type":"VariableDeclarator","range":[7,19]},
2798
					{"type":"Identifier","name":"v","range":[4,5]},
2799
					{"type":"ObjectExpression","range":[9,19]},
2800
					{"type":"Property","kind":"init","range":[12,14]},
2801
					{"type":"Identifier","name":"b","range":[12,12]},
2802
					{"type":"Literal","range":[13,14],"value":1},
2803
					{"type":"Property","kind":"init","range":[15,18]},
2804
					{"type":"Identifier","name":"c","range":[15,16]},
2805
					{"type":"Literal","range":[17,18],"value":2},
2806
					{"type":"FunctionDeclaration","range":[33,54]},
2807
					{"type":"Identifier","name":"f","range":[29,30]},
2808
					{"type":"BlockStatement","range":[34,54]},
2809
					{"type":"ReturnStatement","range":[40,53]},
2810
					{"type":"ObjectExpression","range":[42,52]},
2811
					{"type":"Property","kind":"init","range":[45,47]},
2812
					{"type":"Identifier","name":"b","range":[45,45]},
2813
					{"type":"Literal","range":[46,47],"value":1},
2814
					{"type":"Property","kind":"init","range":[48,51]},
2815
					{"type":"Identifier","name":"c","range":[48,49]},
2816
					{"type":"Literal","range":[50,51],"value":2},
2817
					{"type":"ExpressionStatement","range":[54,69]},
2818
					{"type":"CallExpression","range":[54,68]},
2819
					{"type":"Identifier","name":"f","range":[54,55]},
2820
					{"type":"ObjectExpression","range":[57,67]},
2821
					{"type":"Property","kind":"init","range":[60,62]},
2822
					{"type":"Identifier","name":"b","range":[60,60]},
2823
					{"type":"Literal","range":[61,62],"value":1},
2824
					{"type":"Property","kind":"init","range":[63,66]},
2825
					{"type":"Identifier","name":"c","range":[63,64]},
2826
					{"type":"Literal","range":[65,66],"value":2}],
2827
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2828
					{"type":"Identifier","range":[4,5],"value":"v"},
2829
					{"type":"Punctuator","range":[6,7],"value":"="},
2830
					{"type":"Punctuator","range":[8,9],"value":"{"},
2831
					{"type":"Identifier","range":[9,10],"value":"a"},
2832
					{"type":"Identifier","range":[11,12],"value":"b"},
2833
					{"type":"Punctuator","range":[12,13],"value":":"},
2834
					{"type":"Numeric","range":[13,14],"value":"1"},
2835
					{"type":"Identifier","range":[15,16],"value":"c"},
2836
					{"type":"Punctuator","range":[16,17],"value":":"},
2837
					{"type":"Numeric","range":[17,18],"value":"2"},
2838
					{"type":"Punctuator","range":[18,19],"value":"}"},
2839
					{"type":"Punctuator","range":[19,20],"value":";"},
2840
					{"type":"Keyword","range":[20,28],"value":"function"},
2841
					{"type":"Identifier","range":[29,30],"value":"f"},
2842
					{"type":"Punctuator","range":[30,31],"value":"("},
2843
					{"type":"Punctuator","range":[31,32],"value":")"},
2844
					{"type":"Punctuator","range":[33,34],"value":"{"},
2845
					{"type":"Keyword","range":[34,40],"value":"return"},
2846
					{"type":"Punctuator","range":[41,42],"value":"{"},
2847
					{"type":"Identifier","range":[42,43],"value":"a"},
2848
					{"type":"Identifier","range":[44,45],"value":"b"},
2849
					{"type":"Punctuator","range":[45,46],"value":":"},
2850
					{"type":"Numeric","range":[46,47],"value":"1"},
2851
					{"type":"Identifier","range":[48,49],"value":"c"},
2852
					{"type":"Punctuator","range":[49,50],"value":":"},
2853
					{"type":"Numeric","range":[50,51],"value":"2"},
2854
					{"type":"Punctuator","range":[51,52],"value":"}"},
2855
					{"type":"Punctuator","range":[52,53],"value":";"},
2856
					{"type":"Punctuator","range":[53,54],"value":"}"},
2857
					{"type":"Identifier","range":[54,55],"value":"f"},
2858
					{"type":"Punctuator","range":[55,56],"value":"("},
2859
					{"type":"Punctuator","range":[56,57],"value":"{"},
2860
					{"type":"Identifier","range":[57,58],"value":"a"},
2861
					{"type":"Identifier","range":[59,60],"value":"b"},
2862
					{"type":"Punctuator","range":[60,61],"value":":"},
2863
					{"type":"Numeric","range":[61,62],"value":"1"},
2864
					{"type":"Identifier","range":[63,64],"value":"c"},
2865
					{"type":"Punctuator","range":[64,65],"value":":"},
2866
					{"type":"Numeric","range":[65,66],"value":"2"},
2867
					{"type":"Punctuator","range":[66,67],"value":"}"},
2868
					{"type":"Punctuator","range":[67,68],"value":")"},
2869
					{"type":"Punctuator","range":[68,69],"value":";"}],
2870
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
2871
					{"lineNumber":1,"index":14,"message":"Missing expected ','"},
2872
					{"lineNumber":1,"index":42,"message":"Unexpected token a","token":"a"},
2873
					{"lineNumber":1,"index":47,"message":"Missing expected ','"},
2874
					{"lineNumber":1,"index":57,"message":"Unexpected token a","token":"a"},
2875
					{"lineNumber":1,"index":62,"message":"Missing expected ','"}]
2876
		},
2877
		
2878
		'obj prop recovery - mixed 8': {
2879
			source: 'var v = {a b:1 d c:2};function f() {return {a b:1 d c:2};}f({a b:1 d c:2});',
2880
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,22]},
2881
					{"type":"VariableDeclarator","range":[7,21]},
2882
					{"type":"Identifier","name":"v","range":[4,5]},
2883
					{"type":"ObjectExpression","range":[15,21]},
2884
					{"type":"Property","kind":"init","range":[12,14]},
2885
					{"type":"Identifier","name":"b","range":[12,12]},
2886
					{"type":"Literal","range":[13,14],"value":1},
2887
					{"type":"Property","kind":"init","range":[18,20]},
2888
					{"type":"Identifier","name":"c","range":[18,18]},
2889
					{"type":"Literal","range":[19,20],"value":2},
2890
					{"type":"FunctionDeclaration","range":[36,58]},
2891
					{"type":"Identifier","name":"f","range":[31,32]},
2892
					{"type":"BlockStatement","range":[42,58]},
2893
					{"type":"ReturnStatement","range":[42,57]},
2894
					{"type":"ObjectExpression","range":[50,56]},
2895
					{"type":"Property","kind":"init","range":[47,49]},
2896
					{"type":"Identifier","name":"b","range":[47,47]},
2897
					{"type":"Literal","range":[48,49],"value":1},
2898
					{"type":"Property","kind":"init","range":[53,55]},
2899
					{"type":"Identifier","name":"c","range":[53,53]},
2900
					{"type":"Literal","range":[54,55],"value":2},
2901
					{"type":"ExpressionStatement","range":[58,75]},
2902
					{"type":"CallExpression","range":[58,74]},
2903
					{"type":"Identifier","name":"f","range":[58,59]},
2904
					{"type":"ObjectExpression","range":[67,73]},
2905
					{"type":"Property","kind":"init","range":[64,66]},
2906
					{"type":"Identifier","name":"b","range":[64,64]},
2907
					{"type":"Literal","range":[65,66],"value":1},
2908
					{"type":"Property","kind":"init","range":[70,72]},
2909
					{"type":"Identifier","name":"c","range":[70,70]},
2910
					{"type":"Literal","range":[71,72],"value":2}],
2911
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
2912
					{"type":"Identifier","range":[4,5],"value":"v"},
2913
					{"type":"Punctuator","range":[6,7],"value":"="},
2914
					{"type":"Punctuator","range":[8,9],"value":"{"},
2915
					{"type":"Identifier","range":[9,10],"value":"a"},
2916
					{"type":"Identifier","range":[11,12],"value":"b"},
2917
					{"type":"Punctuator","range":[12,13],"value":":"},
2918
					{"type":"Numeric","range":[13,14],"value":"1"},
2919
					{"type":"Identifier","range":[15,16],"value":"d"},
2920
					{"type":"Identifier","range":[17,18],"value":"c"},
2921
					{"type":"Punctuator","range":[18,19],"value":":"},
2922
					{"type":"Numeric","range":[19,20],"value":"2"},
2923
					{"type":"Punctuator","range":[20,21],"value":"}"},
2924
					{"type":"Punctuator","range":[21,22],"value":";"},
2925
					{"type":"Keyword","range":[22,30],"value":"function"},
2926
					{"type":"Identifier","range":[31,32],"value":"f"},
2927
					{"type":"Punctuator","range":[32,33],"value":"("},
2928
					{"type":"Punctuator","range":[33,34],"value":")"},
2929
					{"type":"Punctuator","range":[35,36],"value":"{"},
2930
					{"type":"Keyword","range":[36,42],"value":"return"},
2931
					{"type":"Punctuator","range":[43,44],"value":"{"},
2932
					{"type":"Identifier","range":[44,45],"value":"a"},
2933
					{"type":"Identifier","range":[46,47],"value":"b"},
2934
					{"type":"Punctuator","range":[47,48],"value":":"},
2935
					{"type":"Numeric","range":[48,49],"value":"1"},
2936
					{"type":"Identifier","range":[50,51],"value":"d"},
2937
					{"type":"Identifier","range":[52,53],"value":"c"},
2938
					{"type":"Punctuator","range":[53,54],"value":":"},
2939
					{"type":"Numeric","range":[54,55],"value":"2"},
2940
					{"type":"Punctuator","range":[55,56],"value":"}"},
2941
					{"type":"Punctuator","range":[56,57],"value":";"},
2942
					{"type":"Punctuator","range":[57,58],"value":"}"},
2943
					{"type":"Identifier","range":[58,59],"value":"f"},
2944
					{"type":"Punctuator","range":[59,60],"value":"("},
2945
					{"type":"Punctuator","range":[60,61],"value":"{"},
2946
					{"type":"Identifier","range":[61,62],"value":"a"},
2947
					{"type":"Identifier","range":[63,64],"value":"b"},
2948
					{"type":"Punctuator","range":[64,65],"value":":"},
2949
					{"type":"Numeric","range":[65,66],"value":"1"},
2950
					{"type":"Identifier","range":[67,68],"value":"d"},
2951
					{"type":"Identifier","range":[69,70],"value":"c"},
2952
					{"type":"Punctuator","range":[70,71],"value":":"},
2953
					{"type":"Numeric","range":[71,72],"value":"2"},
2954
					{"type":"Punctuator","range":[72,73],"value":"}"},
2955
					{"type":"Punctuator","range":[73,74],"value":")"},
2956
					{"type":"Punctuator","range":[74,75],"value":";"}],
2957
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
2958
					{"lineNumber":1,"index":14,"message":"Missing expected ','"},
2959
					{"lineNumber":1,"index":15,"message":"Unexpected token d","token":"d"},
2960
					{"lineNumber":1,"index":44,"message":"Unexpected token a","token":"a"},
2961
					{"lineNumber":1,"index":49,"message":"Missing expected ','"},
2962
					{"lineNumber":1,"index":50,"message":"Unexpected token d","token":"d"},
2963
					{"lineNumber":1,"index":61,"message":"Unexpected token a","token":"a"},
2964
					{"lineNumber":1,"index":66,"message":"Missing expected ','"},
2965
					{"lineNumber":1,"index":67,"message":"Unexpected token d","token":"d"}]
2966
		},
2967
		
2968
		'obj prop recovery - mixed 9': {
2969
			source: 'var v = {a b:{cc:3, dd:\'hey\' e} c:2};function f() {return {a b:{cc:3, dd:\'hey\' e} c:2};}f({a b:{cc:3, dd:\'hey\' e} c:2});',
2970
			nodes: [{"type":"VariableDeclaration","kind":"var","range":[7,37]},
2971
					{"type":"VariableDeclarator","range":[7,36]},
2972
					{"type":"Identifier","name":"v","range":[4,5]},
2973
					{"type":"ObjectExpression","range":[12,36]},
2974
					{"type":"Property","kind":"init","range":[13,31]},
2975
					{"type":"Identifier","name":"b","range":[12,12]},
2976
					{"type":"ObjectExpression","range":[29,31]},
2977
					{"type":"Property","kind":"init","range":[14,18]},
2978
					{"type":"Identifier","name":"cc","range":[14,16]},
2979
					{"type":"Literal","range":[17,18],"value":3},
2980
					{"type":"Property","kind":"init","range":[20,28]},
2981
					{"type":"Identifier","name":"dd","range":[20,22]},
2982
					{"type":"Literal","range":[23,28],"value":"hey"},
2983
					{"type":"Property","kind":"init","range":[32,35]},
2984
					{"type":"Identifier","name":"c","range":[32,33]},
2985
					{"type":"Literal","range":[34,35],"value":2},
2986
					{"type":"FunctionDeclaration","range":[51,88]},
2987
					{"type":"Identifier","name":"f","range":[46,47]},
2988
					{"type":"BlockStatement","range":[57,88]},
2989
					{"type":"ReturnStatement","range":[57,87]},
2990
					{"type":"ObjectExpression","range":[62,86]},
2991
					{"type":"Property","kind":"init","range":[63,81]},
2992
					{"type":"Identifier","name":"b","range":[62,62]},
2993
					{"type":"ObjectExpression","range":[79,81]},
2994
					{"type":"Property","kind":"init","range":[64,68]},
2995
					{"type":"Identifier","name":"cc","range":[64,66]},
2996
					{"type":"Literal","range":[67,68],"value":3},
2997
					{"type":"Property","kind":"init","range":[70,78]},
2998
					{"type":"Identifier","name":"dd","range":[70,72]},
2999
					{"type":"Literal","range":[73,78],"value":"hey"},
3000
					{"type":"Property","kind":"init","range":[82,85]},
3001
					{"type":"Identifier","name":"c","range":[82,83]},
3002
					{"type":"Literal","range":[84,85],"value":2},
3003
					{"type":"ExpressionStatement","range":[88,120]},
3004
					{"type":"CallExpression","range":[88,119]},
3005
					{"type":"Identifier","name":"f","range":[88,89]},
3006
					{"type":"ObjectExpression","range":[94,118]},
3007
					{"type":"Property","kind":"init","range":[95,113]},
3008
					{"type":"Identifier","name":"b","range":[94,94]},
3009
					{"type":"ObjectExpression","range":[111,113]},
3010
					{"type":"Property","kind":"init","range":[96,100]},
3011
					{"type":"Identifier","name":"cc","range":[96,98]},
3012
					{"type":"Literal","range":[99,100],"value":3},
3013
					{"type":"Property","kind":"init","range":[102,110]},
3014
					{"type":"Identifier","name":"dd","range":[102,104]},
3015
					{"type":"Literal","range":[105,110],"value":"hey"},
3016
					{"type":"Property","kind":"init","range":[114,117]},
3017
					{"type":"Identifier","name":"c","range":[114,115]},
3018
					{"type":"Literal","range":[116,117],"value":2}],
3019
			tokens: [{"type":"Keyword","range":[0,3],"value":"var"},
3020
					{"type":"Identifier","range":[4,5],"value":"v"},
3021
					{"type":"Punctuator","range":[6,7],"value":"="},
3022
					{"type":"Punctuator","range":[8,9],"value":"{"},
3023
					{"type":"Identifier","range":[9,10],"value":"a"},
3024
					{"type":"Identifier","range":[11,12],"value":"b"},
3025
					{"type":"Punctuator","range":[12,13],"value":":"},
3026
					{"type":"Punctuator","range":[13,14],"value":"{"},
3027
					{"type":"Identifier","range":[14,16],"value":"cc"},
3028
					{"type":"Punctuator","range":[16,17],"value":":"},
3029
					{"type":"Numeric","range":[17,18],"value":"3"},
3030
					{"type":"Punctuator","range":[18,19],"value":","},
3031
					{"type":"Identifier","range":[20,22],"value":"dd"},
3032
					{"type":"Punctuator","range":[22,23],"value":":"},
3033
					{"type":"String","range":[23,28],"value":"'hey'"},
3034
					{"type":"Identifier","range":[29,30],"value":"e"},
3035
					{"type":"Punctuator","range":[30,31],"value":"}"},
3036
					{"type":"Identifier","range":[32,33],"value":"c"},
3037
					{"type":"Punctuator","range":[33,34],"value":":"},
3038
					{"type":"Numeric","range":[34,35],"value":"2"},
3039
					{"type":"Punctuator","range":[35,36],"value":"}"},
3040
					{"type":"Punctuator","range":[36,37],"value":";"},
3041
					{"type":"Keyword","range":[37,45],"value":"function"},
3042
					{"type":"Identifier","range":[46,47],"value":"f"},
3043
					{"type":"Punctuator","range":[47,48],"value":"("},
3044
					{"type":"Punctuator","range":[48,49],"value":")"},
3045
					{"type":"Punctuator","range":[50,51],"value":"{"},
3046
					{"type":"Keyword","range":[51,57],"value":"return"},
3047
					{"type":"Punctuator","range":[58,59],"value":"{"},
3048
					{"type":"Identifier","range":[59,60],"value":"a"},
3049
					{"type":"Identifier","range":[61,62],"value":"b"},
3050
					{"type":"Punctuator","range":[62,63],"value":":"},
3051
					{"type":"Punctuator","range":[63,64],"value":"{"},
3052
					{"type":"Identifier","range":[64,66],"value":"cc"},
3053
					{"type":"Punctuator","range":[66,67],"value":":"},
3054
					{"type":"Numeric","range":[67,68],"value":"3"},
3055
					{"type":"Punctuator","range":[68,69],"value":","},
3056
					{"type":"Identifier","range":[70,72],"value":"dd"},
3057
					{"type":"Punctuator","range":[72,73],"value":":"},
3058
					{"type":"String","range":[73,78],"value":"'hey'"},
3059
					{"type":"Identifier","range":[79,80],"value":"e"},
3060
					{"type":"Punctuator","range":[80,81],"value":"}"},
3061
					{"type":"Identifier","range":[82,83],"value":"c"},
3062
					{"type":"Punctuator","range":[83,84],"value":":"},
3063
					{"type":"Numeric","range":[84,85],"value":"2"},
3064
					{"type":"Punctuator","range":[85,86],"value":"}"},
3065
					{"type":"Punctuator","range":[86,87],"value":";"},
3066
					{"type":"Punctuator","range":[87,88],"value":"}"},
3067
					{"type":"Identifier","range":[88,89],"value":"f"},
3068
					{"type":"Punctuator","range":[89,90],"value":"("},
3069
					{"type":"Punctuator","range":[90,91],"value":"{"},
3070
					{"type":"Identifier","range":[91,92],"value":"a"},
3071
					{"type":"Identifier","range":[93,94],"value":"b"},
3072
					{"type":"Punctuator","range":[94,95],"value":":"},
3073
					{"type":"Punctuator","range":[95,96],"value":"{"},
3074
					{"type":"Identifier","range":[96,98],"value":"cc"},
3075
					{"type":"Punctuator","range":[98,99],"value":":"},
3076
					{"type":"Numeric","range":[99,100],"value":"3"},
3077
					{"type":"Punctuator","range":[100,101],"value":","},
3078
					{"type":"Identifier","range":[102,104],"value":"dd"},
3079
					{"type":"Punctuator","range":[104,105],"value":":"},
3080
					{"type":"String","range":[105,110],"value":"'hey'"},
3081
					{"type":"Identifier","range":[111,112],"value":"e"},
3082
					{"type":"Punctuator","range":[112,113],"value":"}"},
3083
					{"type":"Identifier","range":[114,115],"value":"c"},
3084
					{"type":"Punctuator","range":[115,116],"value":":"},
3085
					{"type":"Numeric","range":[116,117],"value":"2"},
3086
					{"type":"Punctuator","range":[117,118],"value":"}"},
3087
					{"type":"Punctuator","range":[118,119],"value":")"},
3088
					{"type":"Punctuator","range":[119,120],"value":";"}],
3089
			errors: [{"lineNumber":1,"index":9,"message":"Unexpected token a","token":"a"},
3090
					{"lineNumber":1,"index":28,"message":"Missing expected ','"},
3091
					{"lineNumber":1,"index":29,"message":"Unexpected token e","token":"e"},
3092
					{"lineNumber":1,"index":31,"message":"Missing expected ','"},
3093
					{"lineNumber":1,"index":59,"message":"Unexpected token a","token":"a"},
3094
					{"lineNumber":1,"index":78,"message":"Missing expected ','"},
3095
					{"lineNumber":1,"index":79,"message":"Unexpected token e","token":"e"},
3096
					{"lineNumber":1,"index":81,"message":"Missing expected ','"},
3097
					{"lineNumber":1,"index":91,"message":"Unexpected token a","token":"a"},
3098
					{"lineNumber":1,"index":110,"message":"Missing expected ','"},
3099
					{"lineNumber":1,"index":111,"message":"Unexpected token e","token":"e"},
3100
					{"lineNumber":1,"index":113,"message":"Missing expected ','"}]
3101
		},
359
	};
3102
	};
360
	Object.keys(testData).forEach(function(name) {
3103
	Object.keys(testData).forEach(function(name) {
361
		tests["test " + name] = runTest.bind(tests, name, testData[name]);
3104
		tests["test " + name] = runTest.bind(tests, name, testData[name]);
(-)a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/finderTests.js (-1 / +1 lines)
Lines 400-406 Link Here
400
			var text = "var function f1() {";
400
			var text = "var function f1() {";
401
			return astManager.getAST(setUp(text)).then(function(ast) {
401
			return astManager.getAST(setUp(text)).then(function(ast) {
402
				try {
402
				try {
403
					var token = Finder.findToken(18, ast.tokens);
403
					var token = Finder.findToken(7, ast.tokens);
404
					if(!token) {
404
					if(!token) {
405
						assert.fail("Should have found a token");
405
						assert.fail("Should have found a token");
406
					}
406
					}

Return to bug 432956