PageRenderTime 59ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 1ms

/dist/qunit/blanket.js

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

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