PageRenderTime 66ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/dist/jasmine/blanket_jasmine.js

https://github.com/timplourde/blanket
JavaScript | 5307 lines | 4950 code | 203 blank | 154 comment | 337 complexity | f127db0b2df7e899c74494ab0544e13b MD5 | raw file
Possible License(s): MIT

Large files files are truncated, but you can click here to view the full file

  1. /*! blanket - v1.1.5 */
  2. (function(define){
  3. /*
  4. Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
  5. Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
  6. Copyright (C) 2013 Mathias Bynens <mathias@qiwi.be>
  7. Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
  8. Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
  9. Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
  10. Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
  11. Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
  12. Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
  13. Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
  14. Redistribution and use in source and binary forms, with or without
  15. modification, are permitted provided that the following conditions are met:
  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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  25. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  28. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  30. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. /*jslint bitwise:true plusplus:true */
  33. /*global esprima:true, define:true, exports:true, window: true,
  34. throwErrorTolerant: true,
  35. throwError: true, generateStatement: true, peek: true,
  36. parseAssignmentExpression: true, parseBlock: true, parseExpression: true,
  37. parseFunctionDeclaration: true, parseFunctionExpression: true,
  38. parseFunctionSourceElements: true, parseVariableIdentifier: true,
  39. parseLeftHandSideExpression: true,
  40. parseUnaryExpression: true,
  41. parseStatement: true, parseSourceElement: true */
  42. (function (root, factory) {
  43. 'use strict';
  44. // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
  45. // Rhino, and plain browser loading.
  46. /* istanbul ignore next */
  47. if (typeof define === 'function' && define.amd) {
  48. define(['exports'], factory);
  49. } else if (typeof exports !== 'undefined') {
  50. factory(exports);
  51. } else {
  52. factory((root.esprima = {}));
  53. }
  54. }(this, function (exports) {
  55. 'use strict';
  56. var Token,
  57. TokenName,
  58. FnExprTokens,
  59. Syntax,
  60. PropertyKind,
  61. Messages,
  62. Regex,
  63. SyntaxTreeDelegate,
  64. source,
  65. strict,
  66. index,
  67. lineNumber,
  68. lineStart,
  69. length,
  70. delegate,
  71. lookahead,
  72. state,
  73. extra;
  74. Token = {
  75. BooleanLiteral: 1,
  76. EOF: 2,
  77. Identifier: 3,
  78. Keyword: 4,
  79. NullLiteral: 5,
  80. NumericLiteral: 6,
  81. Punctuator: 7,
  82. StringLiteral: 8,
  83. RegularExpression: 9
  84. };
  85. TokenName = {};
  86. TokenName[Token.BooleanLiteral] = 'Boolean';
  87. TokenName[Token.EOF] = '<end>';
  88. TokenName[Token.Identifier] = 'Identifier';
  89. TokenName[Token.Keyword] = 'Keyword';
  90. TokenName[Token.NullLiteral] = 'Null';
  91. TokenName[Token.NumericLiteral] = 'Numeric';
  92. TokenName[Token.Punctuator] = 'Punctuator';
  93. TokenName[Token.StringLiteral] = 'String';
  94. TokenName[Token.RegularExpression] = 'RegularExpression';
  95. // A function following one of those tokens is an expression.
  96. FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
  97. 'return', 'case', 'delete', 'throw', 'void',
  98. // assignment operators
  99. '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
  100. '&=', '|=', '^=', ',',
  101. // binary/unary operators
  102. '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
  103. '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
  104. '<=', '<', '>', '!=', '!=='];
  105. Syntax = {
  106. AssignmentExpression: 'AssignmentExpression',
  107. ArrayExpression: 'ArrayExpression',
  108. BlockStatement: 'BlockStatement',
  109. BinaryExpression: 'BinaryExpression',
  110. BreakStatement: 'BreakStatement',
  111. CallExpression: 'CallExpression',
  112. CatchClause: 'CatchClause',
  113. ConditionalExpression: 'ConditionalExpression',
  114. ContinueStatement: 'ContinueStatement',
  115. DoWhileStatement: 'DoWhileStatement',
  116. DebuggerStatement: 'DebuggerStatement',
  117. EmptyStatement: 'EmptyStatement',
  118. ExpressionStatement: 'ExpressionStatement',
  119. ForStatement: 'ForStatement',
  120. ForInStatement: 'ForInStatement',
  121. FunctionDeclaration: 'FunctionDeclaration',
  122. FunctionExpression: 'FunctionExpression',
  123. Identifier: 'Identifier',
  124. IfStatement: 'IfStatement',
  125. Literal: 'Literal',
  126. LabeledStatement: 'LabeledStatement',
  127. LogicalExpression: 'LogicalExpression',
  128. MemberExpression: 'MemberExpression',
  129. NewExpression: 'NewExpression',
  130. ObjectExpression: 'ObjectExpression',
  131. Program: 'Program',
  132. Property: 'Property',
  133. ReturnStatement: 'ReturnStatement',
  134. SequenceExpression: 'SequenceExpression',
  135. SwitchStatement: 'SwitchStatement',
  136. SwitchCase: 'SwitchCase',
  137. ThisExpression: 'ThisExpression',
  138. ThrowStatement: 'ThrowStatement',
  139. TryStatement: 'TryStatement',
  140. UnaryExpression: 'UnaryExpression',
  141. UpdateExpression: 'UpdateExpression',
  142. VariableDeclaration: 'VariableDeclaration',
  143. VariableDeclarator: 'VariableDeclarator',
  144. WhileStatement: 'WhileStatement',
  145. WithStatement: 'WithStatement'
  146. };
  147. PropertyKind = {
  148. Data: 1,
  149. Get: 2,
  150. Set: 4
  151. };
  152. // Error messages should be identical to V8.
  153. Messages = {
  154. UnexpectedToken: 'Unexpected token %0',
  155. UnexpectedNumber: 'Unexpected number',
  156. UnexpectedString: 'Unexpected string',
  157. UnexpectedIdentifier: 'Unexpected identifier',
  158. UnexpectedReserved: 'Unexpected reserved word',
  159. UnexpectedEOS: 'Unexpected end of input',
  160. NewlineAfterThrow: 'Illegal newline after throw',
  161. InvalidRegExp: 'Invalid regular expression',
  162. UnterminatedRegExp: 'Invalid regular expression: missing /',
  163. InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
  164. InvalidLHSInForIn: 'Invalid left-hand side in for-in',
  165. MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
  166. NoCatchOrFinally: 'Missing catch or finally after try',
  167. UnknownLabel: 'Undefined label \'%0\'',
  168. Redeclaration: '%0 \'%1\' has already been declared',
  169. IllegalContinue: 'Illegal continue statement',
  170. IllegalBreak: 'Illegal break statement',
  171. IllegalReturn: 'Illegal return statement',
  172. StrictModeWith: 'Strict mode code may not include a with statement',
  173. StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
  174. StrictVarName: 'Variable name may not be eval or arguments in strict mode',
  175. StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
  176. StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
  177. StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
  178. StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
  179. StrictDelete: 'Delete of an unqualified identifier in strict mode.',
  180. StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
  181. AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
  182. AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
  183. StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
  184. StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
  185. StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
  186. StrictReservedWord: 'Use of future reserved word in strict mode'
  187. };
  188. // See also tools/generate-unicode-regex.py.
  189. Regex = {
  190. 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]'),
  191. 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]')
  192. };
  193. // Ensure the condition is true, otherwise throw an error.
  194. // This is only to have a better contract semantic, i.e. another safety net
  195. // to catch a logic error. The condition shall be fulfilled in normal case.
  196. // Do NOT use this to enforce a certain condition on any user input.
  197. function assert(condition, message) {
  198. /* istanbul ignore if */
  199. if (!condition) {
  200. throw new Error('ASSERT: ' + message);
  201. }
  202. }
  203. function isDecimalDigit(ch) {
  204. return (ch >= 48 && ch <= 57); // 0..9
  205. }
  206. function isHexDigit(ch) {
  207. return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
  208. }
  209. function isOctalDigit(ch) {
  210. return '01234567'.indexOf(ch) >= 0;
  211. }
  212. // 7.2 White Space
  213. function isWhiteSpace(ch) {
  214. return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
  215. (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
  216. }
  217. // 7.3 Line Terminators
  218. function isLineTerminator(ch) {
  219. return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
  220. }
  221. // 7.6 Identifier Names and Identifiers
  222. function isIdentifierStart(ch) {
  223. return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
  224. (ch >= 0x41 && ch <= 0x5A) || // A..Z
  225. (ch >= 0x61 && ch <= 0x7A) || // a..z
  226. (ch === 0x5C) || // \ (backslash)
  227. ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
  228. }
  229. function isIdentifierPart(ch) {
  230. return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
  231. (ch >= 0x41 && ch <= 0x5A) || // A..Z
  232. (ch >= 0x61 && ch <= 0x7A) || // a..z
  233. (ch >= 0x30 && ch <= 0x39) || // 0..9
  234. (ch === 0x5C) || // \ (backslash)
  235. ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
  236. }
  237. // 7.6.1.2 Future Reserved Words
  238. function isFutureReservedWord(id) {
  239. switch (id) {
  240. case 'class':
  241. case 'enum':
  242. case 'export':
  243. case 'extends':
  244. case 'import':
  245. case 'super':
  246. return true;
  247. default:
  248. return false;
  249. }
  250. }
  251. function isStrictModeReservedWord(id) {
  252. switch (id) {
  253. case 'implements':
  254. case 'interface':
  255. case 'package':
  256. case 'private':
  257. case 'protected':
  258. case 'public':
  259. case 'static':
  260. case 'yield':
  261. case 'let':
  262. return true;
  263. default:
  264. return false;
  265. }
  266. }
  267. function isRestrictedWord(id) {
  268. return id === 'eval' || id === 'arguments';
  269. }
  270. // 7.6.1.1 Keywords
  271. function isKeyword(id) {
  272. if (strict && isStrictModeReservedWord(id)) {
  273. return true;
  274. }
  275. // 'const' is specialized as Keyword in V8.
  276. // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.
  277. // Some others are from future reserved words.
  278. switch (id.length) {
  279. case 2:
  280. return (id === 'if') || (id === 'in') || (id === 'do');
  281. case 3:
  282. return (id === 'var') || (id === 'for') || (id === 'new') ||
  283. (id === 'try') || (id === 'let');
  284. case 4:
  285. return (id === 'this') || (id === 'else') || (id === 'case') ||
  286. (id === 'void') || (id === 'with') || (id === 'enum');
  287. case 5:
  288. return (id === 'while') || (id === 'break') || (id === 'catch') ||
  289. (id === 'throw') || (id === 'const') || (id === 'yield') ||
  290. (id === 'class') || (id === 'super');
  291. case 6:
  292. return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
  293. (id === 'switch') || (id === 'export') || (id === 'import');
  294. case 7:
  295. return (id === 'default') || (id === 'finally') || (id === 'extends');
  296. case 8:
  297. return (id === 'function') || (id === 'continue') || (id === 'debugger');
  298. case 10:
  299. return (id === 'instanceof');
  300. default:
  301. return false;
  302. }
  303. }
  304. // 7.4 Comments
  305. function addComment(type, value, start, end, loc) {
  306. var comment, attacher;
  307. assert(typeof start === 'number', 'Comment must have valid position');
  308. // Because the way the actual token is scanned, often the comments
  309. // (if any) are skipped twice during the lexical analysis.
  310. // Thus, we need to skip adding a comment if the comment array already
  311. // handled it.
  312. if (state.lastCommentStart >= start) {
  313. return;
  314. }
  315. state.lastCommentStart = start;
  316. comment = {
  317. type: type,
  318. value: value
  319. };
  320. if (extra.range) {
  321. comment.range = [start, end];
  322. }
  323. if (extra.loc) {
  324. comment.loc = loc;
  325. }
  326. extra.comments.push(comment);
  327. if (extra.attachComment) {
  328. extra.leadingComments.push(comment);
  329. extra.trailingComments.push(comment);
  330. }
  331. }
  332. function skipSingleLineComment(offset) {
  333. var start, loc, ch, comment;
  334. start = index - offset;
  335. loc = {
  336. start: {
  337. line: lineNumber,
  338. column: index - lineStart - offset
  339. }
  340. };
  341. while (index < length) {
  342. ch = source.charCodeAt(index);
  343. ++index;
  344. if (isLineTerminator(ch)) {
  345. if (extra.comments) {
  346. comment = source.slice(start + offset, index - 1);
  347. loc.end = {
  348. line: lineNumber,
  349. column: index - lineStart - 1
  350. };
  351. addComment('Line', comment, start, index - 1, loc);
  352. }
  353. if (ch === 13 && source.charCodeAt(index) === 10) {
  354. ++index;
  355. }
  356. ++lineNumber;
  357. lineStart = index;
  358. return;
  359. }
  360. }
  361. if (extra.comments) {
  362. comment = source.slice(start + offset, index);
  363. loc.end = {
  364. line: lineNumber,
  365. column: index - lineStart
  366. };
  367. addComment('Line', comment, start, index, loc);
  368. }
  369. }
  370. function skipMultiLineComment() {
  371. var start, loc, ch, comment;
  372. if (extra.comments) {
  373. start = index - 2;
  374. loc = {
  375. start: {
  376. line: lineNumber,
  377. column: index - lineStart - 2
  378. }
  379. };
  380. }
  381. while (index < length) {
  382. ch = source.charCodeAt(index);
  383. if (isLineTerminator(ch)) {
  384. if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) {
  385. ++index;
  386. }
  387. ++lineNumber;
  388. ++index;
  389. lineStart = index;
  390. if (index >= length) {
  391. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  392. }
  393. } else if (ch === 0x2A) {
  394. // Block comment ends with '*/'.
  395. if (source.charCodeAt(index + 1) === 0x2F) {
  396. ++index;
  397. ++index;
  398. if (extra.comments) {
  399. comment = source.slice(start + 2, index - 2);
  400. loc.end = {
  401. line: lineNumber,
  402. column: index - lineStart
  403. };
  404. addComment('Block', comment, start, index, loc);
  405. }
  406. return;
  407. }
  408. ++index;
  409. } else {
  410. ++index;
  411. }
  412. }
  413. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  414. }
  415. function skipComment() {
  416. var ch, start;
  417. start = (index === 0);
  418. while (index < length) {
  419. ch = source.charCodeAt(index);
  420. if (isWhiteSpace(ch)) {
  421. ++index;
  422. } else if (isLineTerminator(ch)) {
  423. ++index;
  424. if (ch === 0x0D && source.charCodeAt(index) === 0x0A) {
  425. ++index;
  426. }
  427. ++lineNumber;
  428. lineStart = index;
  429. start = true;
  430. } else if (ch === 0x2F) { // U+002F is '/'
  431. ch = source.charCodeAt(index + 1);
  432. if (ch === 0x2F) {
  433. ++index;
  434. ++index;
  435. skipSingleLineComment(2);
  436. start = true;
  437. } else if (ch === 0x2A) { // U+002A is '*'
  438. ++index;
  439. ++index;
  440. skipMultiLineComment();
  441. } else {
  442. break;
  443. }
  444. } else if (start && ch === 0x2D) { // U+002D is '-'
  445. // U+003E is '>'
  446. if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) {
  447. // '-->' is a single-line comment
  448. index += 3;
  449. skipSingleLineComment(3);
  450. } else {
  451. break;
  452. }
  453. } else if (ch === 0x3C) { // U+003C is '<'
  454. if (source.slice(index + 1, index + 4) === '!--') {
  455. ++index; // `<`
  456. ++index; // `!`
  457. ++index; // `-`
  458. ++index; // `-`
  459. skipSingleLineComment(4);
  460. } else {
  461. break;
  462. }
  463. } else {
  464. break;
  465. }
  466. }
  467. }
  468. function scanHexEscape(prefix) {
  469. var i, len, ch, code = 0;
  470. len = (prefix === 'u') ? 4 : 2;
  471. for (i = 0; i < len; ++i) {
  472. if (index < length && isHexDigit(source[index])) {
  473. ch = source[index++];
  474. code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
  475. } else {
  476. return '';
  477. }
  478. }
  479. return String.fromCharCode(code);
  480. }
  481. function getEscapedIdentifier() {
  482. var ch, id;
  483. ch = source.charCodeAt(index++);
  484. id = String.fromCharCode(ch);
  485. // '\u' (U+005C, U+0075) denotes an escaped character.
  486. if (ch === 0x5C) {
  487. if (source.charCodeAt(index) !== 0x75) {
  488. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  489. }
  490. ++index;
  491. ch = scanHexEscape('u');
  492. if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
  493. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  494. }
  495. id = ch;
  496. }
  497. while (index < length) {
  498. ch = source.charCodeAt(index);
  499. if (!isIdentifierPart(ch)) {
  500. break;
  501. }
  502. ++index;
  503. id += String.fromCharCode(ch);
  504. // '\u' (U+005C, U+0075) denotes an escaped character.
  505. if (ch === 0x5C) {
  506. id = id.substr(0, id.length - 1);
  507. if (source.charCodeAt(index) !== 0x75) {
  508. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  509. }
  510. ++index;
  511. ch = scanHexEscape('u');
  512. if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
  513. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  514. }
  515. id += ch;
  516. }
  517. }
  518. return id;
  519. }
  520. function getIdentifier() {
  521. var start, ch;
  522. start = index++;
  523. while (index < length) {
  524. ch = source.charCodeAt(index);
  525. if (ch === 0x5C) {
  526. // Blackslash (U+005C) marks Unicode escape sequence.
  527. index = start;
  528. return getEscapedIdentifier();
  529. }
  530. if (isIdentifierPart(ch)) {
  531. ++index;
  532. } else {
  533. break;
  534. }
  535. }
  536. return source.slice(start, index);
  537. }
  538. function scanIdentifier() {
  539. var start, id, type;
  540. start = index;
  541. // Backslash (U+005C) starts an escaped character.
  542. id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier();
  543. // There is no keyword or literal with only one character.
  544. // Thus, it must be an identifier.
  545. if (id.length === 1) {
  546. type = Token.Identifier;
  547. } else if (isKeyword(id)) {
  548. type = Token.Keyword;
  549. } else if (id === 'null') {
  550. type = Token.NullLiteral;
  551. } else if (id === 'true' || id === 'false') {
  552. type = Token.BooleanLiteral;
  553. } else {
  554. type = Token.Identifier;
  555. }
  556. return {
  557. type: type,
  558. value: id,
  559. lineNumber: lineNumber,
  560. lineStart: lineStart,
  561. start: start,
  562. end: index
  563. };
  564. }
  565. // 7.7 Punctuators
  566. function scanPunctuator() {
  567. var start = index,
  568. code = source.charCodeAt(index),
  569. code2,
  570. ch1 = source[index],
  571. ch2,
  572. ch3,
  573. ch4;
  574. switch (code) {
  575. // Check for most common single-character punctuators.
  576. case 0x2E: // . dot
  577. case 0x28: // ( open bracket
  578. case 0x29: // ) close bracket
  579. case 0x3B: // ; semicolon
  580. case 0x2C: // , comma
  581. case 0x7B: // { open curly brace
  582. case 0x7D: // } close curly brace
  583. case 0x5B: // [
  584. case 0x5D: // ]
  585. case 0x3A: // :
  586. case 0x3F: // ?
  587. case 0x7E: // ~
  588. ++index;
  589. if (extra.tokenize) {
  590. if (code === 0x28) {
  591. extra.openParenToken = extra.tokens.length;
  592. } else if (code === 0x7B) {
  593. extra.openCurlyToken = extra.tokens.length;
  594. }
  595. }
  596. return {
  597. type: Token.Punctuator,
  598. value: String.fromCharCode(code),
  599. lineNumber: lineNumber,
  600. lineStart: lineStart,
  601. start: start,
  602. end: index
  603. };
  604. default:
  605. code2 = source.charCodeAt(index + 1);
  606. // '=' (U+003D) marks an assignment or comparison operator.
  607. if (code2 === 0x3D) {
  608. switch (code) {
  609. case 0x2B: // +
  610. case 0x2D: // -
  611. case 0x2F: // /
  612. case 0x3C: // <
  613. case 0x3E: // >
  614. case 0x5E: // ^
  615. case 0x7C: // |
  616. case 0x25: // %
  617. case 0x26: // &
  618. case 0x2A: // *
  619. index += 2;
  620. return {
  621. type: Token.Punctuator,
  622. value: String.fromCharCode(code) + String.fromCharCode(code2),
  623. lineNumber: lineNumber,
  624. lineStart: lineStart,
  625. start: start,
  626. end: index
  627. };
  628. case 0x21: // !
  629. case 0x3D: // =
  630. index += 2;
  631. // !== and ===
  632. if (source.charCodeAt(index) === 0x3D) {
  633. ++index;
  634. }
  635. return {
  636. type: Token.Punctuator,
  637. value: source.slice(start, index),
  638. lineNumber: lineNumber,
  639. lineStart: lineStart,
  640. start: start,
  641. end: index
  642. };
  643. }
  644. }
  645. }
  646. // 4-character punctuator: >>>=
  647. ch4 = source.substr(index, 4);
  648. if (ch4 === '>>>=') {
  649. index += 4;
  650. return {
  651. type: Token.Punctuator,
  652. value: ch4,
  653. lineNumber: lineNumber,
  654. lineStart: lineStart,
  655. start: start,
  656. end: index
  657. };
  658. }
  659. // 3-character punctuators: === !== >>> <<= >>=
  660. ch3 = ch4.substr(0, 3);
  661. if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') {
  662. index += 3;
  663. return {
  664. type: Token.Punctuator,
  665. value: ch3,
  666. lineNumber: lineNumber,
  667. lineStart: lineStart,
  668. start: start,
  669. end: index
  670. };
  671. }
  672. // Other 2-character punctuators: ++ -- << >> && ||
  673. ch2 = ch3.substr(0, 2);
  674. if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') {
  675. index += 2;
  676. return {
  677. type: Token.Punctuator,
  678. value: ch2,
  679. lineNumber: lineNumber,
  680. lineStart: lineStart,
  681. start: start,
  682. end: index
  683. };
  684. }
  685. // 1-character punctuators: < > = ! + - * % & | ^ /
  686. if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
  687. ++index;
  688. return {
  689. type: Token.Punctuator,
  690. value: ch1,
  691. lineNumber: lineNumber,
  692. lineStart: lineStart,
  693. start: start,
  694. end: index
  695. };
  696. }
  697. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  698. }
  699. // 7.8.3 Numeric Literals
  700. function scanHexLiteral(start) {
  701. var number = '';
  702. while (index < length) {
  703. if (!isHexDigit(source[index])) {
  704. break;
  705. }
  706. number += source[index++];
  707. }
  708. if (number.length === 0) {
  709. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  710. }
  711. if (isIdentifierStart(source.charCodeAt(index))) {
  712. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  713. }
  714. return {
  715. type: Token.NumericLiteral,
  716. value: parseInt('0x' + number, 16),
  717. lineNumber: lineNumber,
  718. lineStart: lineStart,
  719. start: start,
  720. end: index
  721. };
  722. }
  723. function scanOctalLiteral(start) {
  724. var number = '0' + source[index++];
  725. while (index < length) {
  726. if (!isOctalDigit(source[index])) {
  727. break;
  728. }
  729. number += source[index++];
  730. }
  731. if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
  732. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  733. }
  734. return {
  735. type: Token.NumericLiteral,
  736. value: parseInt(number, 8),
  737. octal: true,
  738. lineNumber: lineNumber,
  739. lineStart: lineStart,
  740. start: start,
  741. end: index
  742. };
  743. }
  744. function scanNumericLiteral() {
  745. var number, start, ch;
  746. ch = source[index];
  747. assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
  748. 'Numeric literal must start with a decimal digit or a decimal point');
  749. start = index;
  750. number = '';
  751. if (ch !== '.') {
  752. number = source[index++];
  753. ch = source[index];
  754. // Hex number starts with '0x'.
  755. // Octal number starts with '0'.
  756. if (number === '0') {
  757. if (ch === 'x' || ch === 'X') {
  758. ++index;
  759. return scanHexLiteral(start);
  760. }
  761. if (isOctalDigit(ch)) {
  762. return scanOctalLiteral(start);
  763. }
  764. // decimal number starts with '0' such as '09' is illegal.
  765. if (ch && isDecimalDigit(ch.charCodeAt(0))) {
  766. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  767. }
  768. }
  769. while (isDecimalDigit(source.charCodeAt(index))) {
  770. number += source[index++];
  771. }
  772. ch = source[index];
  773. }
  774. if (ch === '.') {
  775. number += source[index++];
  776. while (isDecimalDigit(source.charCodeAt(index))) {
  777. number += source[index++];
  778. }
  779. ch = source[index];
  780. }
  781. if (ch === 'e' || ch === 'E') {
  782. number += source[index++];
  783. ch = source[index];
  784. if (ch === '+' || ch === '-') {
  785. number += source[index++];
  786. }
  787. if (isDecimalDigit(source.charCodeAt(index))) {
  788. while (isDecimalDigit(source.charCodeAt(index))) {
  789. number += source[index++];
  790. }
  791. } else {
  792. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  793. }
  794. }
  795. if (isIdentifierStart(source.charCodeAt(index))) {
  796. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  797. }
  798. return {
  799. type: Token.NumericLiteral,
  800. value: parseFloat(number),
  801. lineNumber: lineNumber,
  802. lineStart: lineStart,
  803. start: start,
  804. end: index
  805. };
  806. }
  807. // 7.8.4 String Literals
  808. function scanStringLiteral() {
  809. var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart;
  810. startLineNumber = lineNumber;
  811. startLineStart = lineStart;
  812. quote = source[index];
  813. assert((quote === '\'' || quote === '"'),
  814. 'String literal must starts with a quote');
  815. start = index;
  816. ++index;
  817. while (index < length) {
  818. ch = source[index++];
  819. if (ch === quote) {
  820. quote = '';
  821. break;
  822. } else if (ch === '\\') {
  823. ch = source[index++];
  824. if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
  825. switch (ch) {
  826. case 'u':
  827. case 'x':
  828. restore = index;
  829. unescaped = scanHexEscape(ch);
  830. if (unescaped) {
  831. str += unescaped;
  832. } else {
  833. index = restore;
  834. str += ch;
  835. }
  836. break;
  837. case 'n':
  838. str += '\n';
  839. break;
  840. case 'r':
  841. str += '\r';
  842. break;
  843. case 't':
  844. str += '\t';
  845. break;
  846. case 'b':
  847. str += '\b';
  848. break;
  849. case 'f':
  850. str += '\f';
  851. break;
  852. case 'v':
  853. str += '\x0B';
  854. break;
  855. default:
  856. if (isOctalDigit(ch)) {
  857. code = '01234567'.indexOf(ch);
  858. // \0 is not octal escape sequence
  859. if (code !== 0) {
  860. octal = true;
  861. }
  862. if (index < length && isOctalDigit(source[index])) {
  863. octal = true;
  864. code = code * 8 + '01234567'.indexOf(source[index++]);
  865. // 3 digits are only allowed when string starts
  866. // with 0, 1, 2, 3
  867. if ('0123'.indexOf(ch) >= 0 &&
  868. index < length &&
  869. isOctalDigit(source[index])) {
  870. code = code * 8 + '01234567'.indexOf(source[index++]);
  871. }
  872. }
  873. str += String.fromCharCode(code);
  874. } else {
  875. str += ch;
  876. }
  877. break;
  878. }
  879. } else {
  880. ++lineNumber;
  881. if (ch === '\r' && source[index] === '\n') {
  882. ++index;
  883. }
  884. lineStart = index;
  885. }
  886. } else if (isLineTerminator(ch.charCodeAt(0))) {
  887. break;
  888. } else {
  889. str += ch;
  890. }
  891. }
  892. if (quote !== '') {
  893. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  894. }
  895. return {
  896. type: Token.StringLiteral,
  897. value: str,
  898. octal: octal,
  899. startLineNumber: startLineNumber,
  900. startLineStart: startLineStart,
  901. lineNumber: lineNumber,
  902. lineStart: lineStart,
  903. start: start,
  904. end: index
  905. };
  906. }
  907. function testRegExp(pattern, flags) {
  908. var value;
  909. try {
  910. value = new RegExp(pattern, flags);
  911. } catch (e) {
  912. throwError({}, Messages.InvalidRegExp);
  913. }
  914. return value;
  915. }
  916. function scanRegExpBody() {
  917. var ch, str, classMarker, terminated, body;
  918. ch = source[index];
  919. assert(ch === '/', 'Regular expression literal must start with a slash');
  920. str = source[index++];
  921. classMarker = false;
  922. terminated = false;
  923. while (index < length) {
  924. ch = source[index++];
  925. str += ch;
  926. if (ch === '\\') {
  927. ch = source[index++];
  928. // ECMA-262 7.8.5
  929. if (isLineTerminator(ch.charCodeAt(0))) {
  930. throwError({}, Messages.UnterminatedRegExp);
  931. }
  932. str += ch;
  933. } else if (isLineTerminator(ch.charCodeAt(0))) {
  934. throwError({}, Messages.UnterminatedRegExp);
  935. } else if (classMarker) {
  936. if (ch === ']') {
  937. classMarker = false;
  938. }
  939. } else {
  940. if (ch === '/') {
  941. terminated = true;
  942. break;
  943. } else if (ch === '[') {
  944. classMarker = true;
  945. }
  946. }
  947. }
  948. if (!terminated) {
  949. throwError({}, Messages.UnterminatedRegExp);
  950. }
  951. // Exclude leading and trailing slash.
  952. body = str.substr(1, str.length - 2);
  953. return {
  954. value: body,
  955. literal: str
  956. };
  957. }
  958. function scanRegExpFlags() {
  959. var ch, str, flags, restore;
  960. str = '';
  961. flags = '';
  962. while (index < length) {
  963. ch = source[index];
  964. if (!isIdentifierPart(ch.charCodeAt(0))) {
  965. break;
  966. }
  967. ++index;
  968. if (ch === '\\' && index < length) {
  969. ch = source[index];
  970. if (ch === 'u') {
  971. ++index;
  972. restore = index;
  973. ch = scanHexEscape('u');
  974. if (ch) {
  975. flags += ch;
  976. for (str += '\\u'; restore < index; ++restore) {
  977. str += source[restore];
  978. }
  979. } else {
  980. index = restore;
  981. flags += 'u';
  982. str += '\\u';
  983. }
  984. throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
  985. } else {
  986. str += '\\';
  987. throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
  988. }
  989. } else {
  990. flags += ch;
  991. str += ch;
  992. }
  993. }
  994. return {
  995. value: flags,
  996. literal: str
  997. };
  998. }
  999. function scanRegExp() {
  1000. var start, body, flags, pattern, value;
  1001. lookahead = null;
  1002. skipComment();
  1003. start = index;
  1004. body = scanRegExpBody();
  1005. flags = scanRegExpFlags();
  1006. value = testRegExp(body.value, flags.value);
  1007. if (extra.tokenize) {
  1008. return {
  1009. type: Token.RegularExpression,
  1010. value: value,
  1011. lineNumber: lineNumber,
  1012. lineStart: lineStart,
  1013. start: start,
  1014. end: index
  1015. };
  1016. }
  1017. return {
  1018. literal: body.literal + flags.literal,
  1019. value: value,
  1020. start: start,
  1021. end: index
  1022. };
  1023. }
  1024. function collectRegex() {
  1025. var pos, loc, regex, token;
  1026. skipComment();
  1027. pos = index;
  1028. loc = {
  1029. start: {
  1030. line: lineNumber,
  1031. column: index - lineStart
  1032. }
  1033. };
  1034. regex = scanRegExp();
  1035. loc.end = {
  1036. line: lineNumber,
  1037. column: index - lineStart
  1038. };
  1039. /* istanbul ignore next */
  1040. if (!extra.tokenize) {
  1041. // Pop the previous token, which is likely '/' or '/='
  1042. if (extra.tokens.length > 0) {
  1043. token = extra.tokens[extra.tokens.length - 1];
  1044. if (token.range[0] === pos && token.type === 'Punctuator') {
  1045. if (token.value === '/' || token.value === '/=') {
  1046. extra.tokens.pop();
  1047. }
  1048. }
  1049. }
  1050. extra.tokens.push({
  1051. type: 'RegularExpression',
  1052. value: regex.literal,
  1053. range: [pos, index],
  1054. loc: loc
  1055. });
  1056. }
  1057. return regex;
  1058. }
  1059. function isIdentifierName(token) {
  1060. return token.type === Token.Identifier ||
  1061. token.type === Token.Keyword ||
  1062. token.type === Token.BooleanLiteral ||
  1063. token.type === Token.NullLiteral;
  1064. }
  1065. function advanceSlash() {
  1066. var prevToken,
  1067. checkToken;
  1068. // Using the following algorithm:
  1069. // https://github.com/mozilla/sweet.js/wiki/design
  1070. prevToken = extra.tokens[extra.tokens.length - 1];
  1071. if (!prevToken) {
  1072. // Nothing before that: it cannot be a division.
  1073. return collectRegex();
  1074. }
  1075. if (prevToken.type === 'Punctuator') {
  1076. if (prevToken.value === ']') {
  1077. return scanPunctuator();
  1078. }
  1079. if (prevToken.value === ')') {
  1080. checkToken = extra.tokens[extra.openParenToken - 1];
  1081. if (checkToken &&
  1082. checkToken.type === 'Keyword' &&
  1083. (checkToken.value === 'if' ||
  1084. checkToken.value === 'while' ||
  1085. checkToken.value === 'for' ||
  1086. checkToken.value === 'with')) {
  1087. return collectRegex();
  1088. }
  1089. return scanPunctuator();
  1090. }
  1091. if (prevToken.value === '}') {
  1092. // Dividing a function by anything makes little sense,
  1093. // but we have to check for that.
  1094. if

Large files files are truncated, but you can click here to view the full file