No Description

esprima.js 122KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908
  1. /*
  2. Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
  3. Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
  4. Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
  5. Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
  6. Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
  7. Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
  8. Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
  9. Redistribution and use in source and binary forms, with or without
  10. modification, are permitted provided that the following conditions are met:
  11. * Redistributions of source code must retain the above copyright
  12. notice, this list of conditions and the following disclaimer.
  13. * Redistributions in binary form must reproduce the above copyright
  14. notice, this list of conditions and the following disclaimer in the
  15. documentation and/or other materials provided with the distribution.
  16. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  20. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. /*jslint bitwise:true plusplus:true */
  28. /*global esprima:true, define:true, exports:true, window: true,
  29. throwError: true, createLiteral: true, generateStatement: true,
  30. parseAssignmentExpression: true, parseBlock: true, parseExpression: true,
  31. parseFunctionDeclaration: true, parseFunctionExpression: true,
  32. parseFunctionSourceElements: true, parseVariableIdentifier: true,
  33. parseLeftHandSideExpression: true,
  34. parseStatement: true, parseSourceElement: true */
  35. (function (root, factory) {
  36. 'use strict';
  37. // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
  38. // Rhino, and plain browser loading.
  39. if (typeof define === 'function' && define.amd) {
  40. define(['exports'], factory);
  41. } else if (typeof exports !== 'undefined') {
  42. factory(exports);
  43. } else {
  44. factory((root.esprima = {}));
  45. }
  46. }(this, function (exports) {
  47. 'use strict';
  48. var Token,
  49. TokenName,
  50. Syntax,
  51. PropertyKind,
  52. Messages,
  53. Regex,
  54. source,
  55. strict,
  56. index,
  57. lineNumber,
  58. lineStart,
  59. length,
  60. buffer,
  61. state,
  62. extra;
  63. Token = {
  64. BooleanLiteral: 1,
  65. EOF: 2,
  66. Identifier: 3,
  67. Keyword: 4,
  68. NullLiteral: 5,
  69. NumericLiteral: 6,
  70. Punctuator: 7,
  71. StringLiteral: 8
  72. };
  73. TokenName = {};
  74. TokenName[Token.BooleanLiteral] = 'Boolean';
  75. TokenName[Token.EOF] = '<end>';
  76. TokenName[Token.Identifier] = 'Identifier';
  77. TokenName[Token.Keyword] = 'Keyword';
  78. TokenName[Token.NullLiteral] = 'Null';
  79. TokenName[Token.NumericLiteral] = 'Numeric';
  80. TokenName[Token.Punctuator] = 'Punctuator';
  81. TokenName[Token.StringLiteral] = 'String';
  82. Syntax = {
  83. AssignmentExpression: 'AssignmentExpression',
  84. ArrayExpression: 'ArrayExpression',
  85. BlockStatement: 'BlockStatement',
  86. BinaryExpression: 'BinaryExpression',
  87. BreakStatement: 'BreakStatement',
  88. CallExpression: 'CallExpression',
  89. CatchClause: 'CatchClause',
  90. ConditionalExpression: 'ConditionalExpression',
  91. ContinueStatement: 'ContinueStatement',
  92. DoWhileStatement: 'DoWhileStatement',
  93. DebuggerStatement: 'DebuggerStatement',
  94. EmptyStatement: 'EmptyStatement',
  95. ExpressionStatement: 'ExpressionStatement',
  96. ForStatement: 'ForStatement',
  97. ForInStatement: 'ForInStatement',
  98. FunctionDeclaration: 'FunctionDeclaration',
  99. FunctionExpression: 'FunctionExpression',
  100. Identifier: 'Identifier',
  101. IfStatement: 'IfStatement',
  102. Literal: 'Literal',
  103. LabeledStatement: 'LabeledStatement',
  104. LogicalExpression: 'LogicalExpression',
  105. MemberExpression: 'MemberExpression',
  106. NewExpression: 'NewExpression',
  107. ObjectExpression: 'ObjectExpression',
  108. Program: 'Program',
  109. Property: 'Property',
  110. ReturnStatement: 'ReturnStatement',
  111. SequenceExpression: 'SequenceExpression',
  112. SwitchStatement: 'SwitchStatement',
  113. SwitchCase: 'SwitchCase',
  114. ThisExpression: 'ThisExpression',
  115. ThrowStatement: 'ThrowStatement',
  116. TryStatement: 'TryStatement',
  117. UnaryExpression: 'UnaryExpression',
  118. UpdateExpression: 'UpdateExpression',
  119. VariableDeclaration: 'VariableDeclaration',
  120. VariableDeclarator: 'VariableDeclarator',
  121. WhileStatement: 'WhileStatement',
  122. WithStatement: 'WithStatement'
  123. };
  124. PropertyKind = {
  125. Data: 1,
  126. Get: 2,
  127. Set: 4
  128. };
  129. // Error messages should be identical to V8.
  130. Messages = {
  131. UnexpectedToken: 'Unexpected token %0',
  132. UnexpectedNumber: 'Unexpected number',
  133. UnexpectedString: 'Unexpected string',
  134. UnexpectedIdentifier: 'Unexpected identifier',
  135. UnexpectedReserved: 'Unexpected reserved word',
  136. UnexpectedEOS: 'Unexpected end of input',
  137. NewlineAfterThrow: 'Illegal newline after throw',
  138. InvalidRegExp: 'Invalid regular expression',
  139. UnterminatedRegExp: 'Invalid regular expression: missing /',
  140. InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
  141. InvalidLHSInForIn: 'Invalid left-hand side in for-in',
  142. MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
  143. NoCatchOrFinally: 'Missing catch or finally after try',
  144. UnknownLabel: 'Undefined label \'%0\'',
  145. Redeclaration: '%0 \'%1\' has already been declared',
  146. IllegalContinue: 'Illegal continue statement',
  147. IllegalBreak: 'Illegal break statement',
  148. IllegalReturn: 'Illegal return statement',
  149. StrictModeWith: 'Strict mode code may not include a with statement',
  150. StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
  151. StrictVarName: 'Variable name may not be eval or arguments in strict mode',
  152. StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
  153. StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
  154. StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
  155. StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
  156. StrictDelete: 'Delete of an unqualified identifier in strict mode.',
  157. StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
  158. AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
  159. AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
  160. StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
  161. StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
  162. StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
  163. StrictReservedWord: 'Use of future reserved word in strict mode'
  164. };
  165. // See also tools/generate-unicode-regex.py.
  166. Regex = {
  167. 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]'),
  168. 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]')
  169. };
  170. // Ensure the condition is true, otherwise throw an error.
  171. // This is only to have a better contract semantic, i.e. another safety net
  172. // to catch a logic error. The condition shall be fulfilled in normal case.
  173. // Do NOT use this to enforce a certain condition on any user input.
  174. function assert(condition, message) {
  175. if (!condition) {
  176. throw new Error('ASSERT: ' + message);
  177. }
  178. }
  179. function sliceSource(from, to) {
  180. return source.slice(from, to);
  181. }
  182. if (typeof 'esprima'[0] === 'undefined') {
  183. sliceSource = function sliceArraySource(from, to) {
  184. return source.slice(from, to).join('');
  185. };
  186. }
  187. function isDecimalDigit(ch) {
  188. return '0123456789'.indexOf(ch) >= 0;
  189. }
  190. function isHexDigit(ch) {
  191. return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
  192. }
  193. function isOctalDigit(ch) {
  194. return '01234567'.indexOf(ch) >= 0;
  195. }
  196. // 7.2 White Space
  197. function isWhiteSpace(ch) {
  198. return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') ||
  199. (ch === '\u000C') || (ch === '\u00A0') ||
  200. (ch.charCodeAt(0) >= 0x1680 &&
  201. '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0);
  202. }
  203. // 7.3 Line Terminators
  204. function isLineTerminator(ch) {
  205. return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');
  206. }
  207. // 7.6 Identifier Names and Identifiers
  208. function isIdentifierStart(ch) {
  209. return (ch === '$') || (ch === '_') || (ch === '\\') ||
  210. (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
  211. ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierStart.test(ch));
  212. }
  213. function isIdentifierPart(ch) {
  214. return (ch === '$') || (ch === '_') || (ch === '\\') ||
  215. (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
  216. ((ch >= '0') && (ch <= '9')) ||
  217. ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierPart.test(ch));
  218. }
  219. // 7.6.1.2 Future Reserved Words
  220. function isFutureReservedWord(id) {
  221. switch (id) {
  222. // Future reserved words.
  223. case 'class':
  224. case 'enum':
  225. case 'export':
  226. case 'extends':
  227. case 'import':
  228. case 'super':
  229. return true;
  230. }
  231. return false;
  232. }
  233. function isStrictModeReservedWord(id) {
  234. switch (id) {
  235. // Strict Mode reserved words.
  236. case 'implements':
  237. case 'interface':
  238. case 'package':
  239. case 'private':
  240. case 'protected':
  241. case 'public':
  242. case 'static':
  243. case 'yield':
  244. case 'let':
  245. return true;
  246. }
  247. return false;
  248. }
  249. function isRestrictedWord(id) {
  250. return id === 'eval' || id === 'arguments';
  251. }
  252. // 7.6.1.1 Keywords
  253. function isKeyword(id) {
  254. var keyword = false;
  255. switch (id.length) {
  256. case 2:
  257. keyword = (id === 'if') || (id === 'in') || (id === 'do');
  258. break;
  259. case 3:
  260. keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');
  261. break;
  262. case 4:
  263. keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with');
  264. break;
  265. case 5:
  266. keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw');
  267. break;
  268. case 6:
  269. keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch');
  270. break;
  271. case 7:
  272. keyword = (id === 'default') || (id === 'finally');
  273. break;
  274. case 8:
  275. keyword = (id === 'function') || (id === 'continue') || (id === 'debugger');
  276. break;
  277. case 10:
  278. keyword = (id === 'instanceof');
  279. break;
  280. }
  281. if (keyword) {
  282. return true;
  283. }
  284. switch (id) {
  285. // Future reserved words.
  286. // 'const' is specialized as Keyword in V8.
  287. case 'const':
  288. return true;
  289. // For compatiblity to SpiderMonkey and ES.next
  290. case 'yield':
  291. case 'let':
  292. return true;
  293. }
  294. if (strict && isStrictModeReservedWord(id)) {
  295. return true;
  296. }
  297. return isFutureReservedWord(id);
  298. }
  299. // 7.4 Comments
  300. function skipComment() {
  301. var ch, blockComment, lineComment;
  302. blockComment = false;
  303. lineComment = false;
  304. while (index < length) {
  305. ch = source[index];
  306. if (lineComment) {
  307. ch = source[index++];
  308. if (isLineTerminator(ch)) {
  309. lineComment = false;
  310. if (ch === '\r' && source[index] === '\n') {
  311. ++index;
  312. }
  313. ++lineNumber;
  314. lineStart = index;
  315. }
  316. } else if (blockComment) {
  317. if (isLineTerminator(ch)) {
  318. if (ch === '\r' && source[index + 1] === '\n') {
  319. ++index;
  320. }
  321. ++lineNumber;
  322. ++index;
  323. lineStart = index;
  324. if (index >= length) {
  325. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  326. }
  327. } else {
  328. ch = source[index++];
  329. if (index >= length) {
  330. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  331. }
  332. if (ch === '*') {
  333. ch = source[index];
  334. if (ch === '/') {
  335. ++index;
  336. blockComment = false;
  337. }
  338. }
  339. }
  340. } else if (ch === '/') {
  341. ch = source[index + 1];
  342. if (ch === '/') {
  343. index += 2;
  344. lineComment = true;
  345. } else if (ch === '*') {
  346. index += 2;
  347. blockComment = true;
  348. if (index >= length) {
  349. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  350. }
  351. } else {
  352. break;
  353. }
  354. } else if (isWhiteSpace(ch)) {
  355. ++index;
  356. } else if (isLineTerminator(ch)) {
  357. ++index;
  358. if (ch === '\r' && source[index] === '\n') {
  359. ++index;
  360. }
  361. ++lineNumber;
  362. lineStart = index;
  363. } else {
  364. break;
  365. }
  366. }
  367. }
  368. function scanHexEscape(prefix) {
  369. var i, len, ch, code = 0;
  370. len = (prefix === 'u') ? 4 : 2;
  371. for (i = 0; i < len; ++i) {
  372. if (index < length && isHexDigit(source[index])) {
  373. ch = source[index++];
  374. code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
  375. } else {
  376. return '';
  377. }
  378. }
  379. return String.fromCharCode(code);
  380. }
  381. function scanIdentifier() {
  382. var ch, start, id, restore;
  383. ch = source[index];
  384. if (!isIdentifierStart(ch)) {
  385. return;
  386. }
  387. start = index;
  388. if (ch === '\\') {
  389. ++index;
  390. if (source[index] !== 'u') {
  391. return;
  392. }
  393. ++index;
  394. restore = index;
  395. ch = scanHexEscape('u');
  396. if (ch) {
  397. if (ch === '\\' || !isIdentifierStart(ch)) {
  398. return;
  399. }
  400. id = ch;
  401. } else {
  402. index = restore;
  403. id = 'u';
  404. }
  405. } else {
  406. id = source[index++];
  407. }
  408. while (index < length) {
  409. ch = source[index];
  410. if (!isIdentifierPart(ch)) {
  411. break;
  412. }
  413. if (ch === '\\') {
  414. ++index;
  415. if (source[index] !== 'u') {
  416. return;
  417. }
  418. ++index;
  419. restore = index;
  420. ch = scanHexEscape('u');
  421. if (ch) {
  422. if (ch === '\\' || !isIdentifierPart(ch)) {
  423. return;
  424. }
  425. id += ch;
  426. } else {
  427. index = restore;
  428. id += 'u';
  429. }
  430. } else {
  431. id += source[index++];
  432. }
  433. }
  434. // There is no keyword or literal with only one character.
  435. // Thus, it must be an identifier.
  436. if (id.length === 1) {
  437. return {
  438. type: Token.Identifier,
  439. value: id,
  440. lineNumber: lineNumber,
  441. lineStart: lineStart,
  442. range: [start, index]
  443. };
  444. }
  445. if (isKeyword(id)) {
  446. return {
  447. type: Token.Keyword,
  448. value: id,
  449. lineNumber: lineNumber,
  450. lineStart: lineStart,
  451. range: [start, index]
  452. };
  453. }
  454. // 7.8.1 Null Literals
  455. if (id === 'null') {
  456. return {
  457. type: Token.NullLiteral,
  458. value: id,
  459. lineNumber: lineNumber,
  460. lineStart: lineStart,
  461. range: [start, index]
  462. };
  463. }
  464. // 7.8.2 Boolean Literals
  465. if (id === 'true' || id === 'false') {
  466. return {
  467. type: Token.BooleanLiteral,
  468. value: id,
  469. lineNumber: lineNumber,
  470. lineStart: lineStart,
  471. range: [start, index]
  472. };
  473. }
  474. return {
  475. type: Token.Identifier,
  476. value: id,
  477. lineNumber: lineNumber,
  478. lineStart: lineStart,
  479. range: [start, index]
  480. };
  481. }
  482. // 7.7 Punctuators
  483. function scanPunctuator() {
  484. var start = index,
  485. ch1 = source[index],
  486. ch2,
  487. ch3,
  488. ch4;
  489. // Check for most common single-character punctuators.
  490. if (ch1 === ';' || ch1 === '{' || ch1 === '}') {
  491. ++index;
  492. return {
  493. type: Token.Punctuator,
  494. value: ch1,
  495. lineNumber: lineNumber,
  496. lineStart: lineStart,
  497. range: [start, index]
  498. };
  499. }
  500. if (ch1 === ',' || ch1 === '(' || ch1 === ')') {
  501. ++index;
  502. return {
  503. type: Token.Punctuator,
  504. value: ch1,
  505. lineNumber: lineNumber,
  506. lineStart: lineStart,
  507. range: [start, index]
  508. };
  509. }
  510. // Dot (.) can also start a floating-point number, hence the need
  511. // to check the next character.
  512. ch2 = source[index + 1];
  513. if (ch1 === '.' && !isDecimalDigit(ch2)) {
  514. return {
  515. type: Token.Punctuator,
  516. value: source[index++],
  517. lineNumber: lineNumber,
  518. lineStart: lineStart,
  519. range: [start, index]
  520. };
  521. }
  522. // Peek more characters.
  523. ch3 = source[index + 2];
  524. ch4 = source[index + 3];
  525. // 4-character punctuator: >>>=
  526. if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
  527. if (ch4 === '=') {
  528. index += 4;
  529. return {
  530. type: Token.Punctuator,
  531. value: '>>>=',
  532. lineNumber: lineNumber,
  533. lineStart: lineStart,
  534. range: [start, index]
  535. };
  536. }
  537. }
  538. // 3-character punctuators: === !== >>> <<= >>=
  539. if (ch1 === '=' && ch2 === '=' && ch3 === '=') {
  540. index += 3;
  541. return {
  542. type: Token.Punctuator,
  543. value: '===',
  544. lineNumber: lineNumber,
  545. lineStart: lineStart,
  546. range: [start, index]
  547. };
  548. }
  549. if (ch1 === '!' && ch2 === '=' && ch3 === '=') {
  550. index += 3;
  551. return {
  552. type: Token.Punctuator,
  553. value: '!==',
  554. lineNumber: lineNumber,
  555. lineStart: lineStart,
  556. range: [start, index]
  557. };
  558. }
  559. if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
  560. index += 3;
  561. return {
  562. type: Token.Punctuator,
  563. value: '>>>',
  564. lineNumber: lineNumber,
  565. lineStart: lineStart,
  566. range: [start, index]
  567. };
  568. }
  569. if (ch1 === '<' && ch2 === '<' && ch3 === '=') {
  570. index += 3;
  571. return {
  572. type: Token.Punctuator,
  573. value: '<<=',
  574. lineNumber: lineNumber,
  575. lineStart: lineStart,
  576. range: [start, index]
  577. };
  578. }
  579. if (ch1 === '>' && ch2 === '>' && ch3 === '=') {
  580. index += 3;
  581. return {
  582. type: Token.Punctuator,
  583. value: '>>=',
  584. lineNumber: lineNumber,
  585. lineStart: lineStart,
  586. range: [start, index]
  587. };
  588. }
  589. // 2-character punctuators: <= >= == != ++ -- << >> && ||
  590. // += -= *= %= &= |= ^= /=
  591. if (ch2 === '=') {
  592. if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
  593. index += 2;
  594. return {
  595. type: Token.Punctuator,
  596. value: ch1 + ch2,
  597. lineNumber: lineNumber,
  598. lineStart: lineStart,
  599. range: [start, index]
  600. };
  601. }
  602. }
  603. if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {
  604. if ('+-<>&|'.indexOf(ch2) >= 0) {
  605. index += 2;
  606. return {
  607. type: Token.Punctuator,
  608. value: ch1 + ch2,
  609. lineNumber: lineNumber,
  610. lineStart: lineStart,
  611. range: [start, index]
  612. };
  613. }
  614. }
  615. // The remaining 1-character punctuators.
  616. if ('[]<>+-*%&|^!~?:=/'.indexOf(ch1) >= 0) {
  617. return {
  618. type: Token.Punctuator,
  619. value: source[index++],
  620. lineNumber: lineNumber,
  621. lineStart: lineStart,
  622. range: [start, index]
  623. };
  624. }
  625. }
  626. // 7.8.3 Numeric Literals
  627. function scanNumericLiteral() {
  628. var number, start, ch;
  629. ch = source[index];
  630. assert(isDecimalDigit(ch) || (ch === '.'),
  631. 'Numeric literal must start with a decimal digit or a decimal point');
  632. start = index;
  633. number = '';
  634. if (ch !== '.') {
  635. number = source[index++];
  636. ch = source[index];
  637. // Hex number starts with '0x'.
  638. // Octal number starts with '0'.
  639. if (number === '0') {
  640. if (ch === 'x' || ch === 'X') {
  641. number += source[index++];
  642. while (index < length) {
  643. ch = source[index];
  644. if (!isHexDigit(ch)) {
  645. break;
  646. }
  647. number += source[index++];
  648. }
  649. if (number.length <= 2) {
  650. // only 0x
  651. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  652. }
  653. if (index < length) {
  654. ch = source[index];
  655. if (isIdentifierStart(ch)) {
  656. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  657. }
  658. }
  659. return {
  660. type: Token.NumericLiteral,
  661. value: parseInt(number, 16),
  662. lineNumber: lineNumber,
  663. lineStart: lineStart,
  664. range: [start, index]
  665. };
  666. } else if (isOctalDigit(ch)) {
  667. number += source[index++];
  668. while (index < length) {
  669. ch = source[index];
  670. if (!isOctalDigit(ch)) {
  671. break;
  672. }
  673. number += source[index++];
  674. }
  675. if (index < length) {
  676. ch = source[index];
  677. if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
  678. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  679. }
  680. }
  681. return {
  682. type: Token.NumericLiteral,
  683. value: parseInt(number, 8),
  684. octal: true,
  685. lineNumber: lineNumber,
  686. lineStart: lineStart,
  687. range: [start, index]
  688. };
  689. }
  690. // decimal number starts with '0' such as '09' is illegal.
  691. if (isDecimalDigit(ch)) {
  692. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  693. }
  694. }
  695. while (index < length) {
  696. ch = source[index];
  697. if (!isDecimalDigit(ch)) {
  698. break;
  699. }
  700. number += source[index++];
  701. }
  702. }
  703. if (ch === '.') {
  704. number += source[index++];
  705. while (index < length) {
  706. ch = source[index];
  707. if (!isDecimalDigit(ch)) {
  708. break;
  709. }
  710. number += source[index++];
  711. }
  712. }
  713. if (ch === 'e' || ch === 'E') {
  714. number += source[index++];
  715. ch = source[index];
  716. if (ch === '+' || ch === '-') {
  717. number += source[index++];
  718. }
  719. ch = source[index];
  720. if (isDecimalDigit(ch)) {
  721. number += source[index++];
  722. while (index < length) {
  723. ch = source[index];
  724. if (!isDecimalDigit(ch)) {
  725. break;
  726. }
  727. number += source[index++];
  728. }
  729. } else {
  730. ch = 'character ' + ch;
  731. if (index >= length) {
  732. ch = '<end>';
  733. }
  734. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  735. }
  736. }
  737. if (index < length) {
  738. ch = source[index];
  739. if (isIdentifierStart(ch)) {
  740. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  741. }
  742. }
  743. return {
  744. type: Token.NumericLiteral,
  745. value: parseFloat(number),
  746. lineNumber: lineNumber,
  747. lineStart: lineStart,
  748. range: [start, index]
  749. };
  750. }
  751. // 7.8.4 String Literals
  752. function scanStringLiteral() {
  753. var str = '', quote, start, ch, code, unescaped, restore, octal = false;
  754. quote = source[index];
  755. assert((quote === '\'' || quote === '"'),
  756. 'String literal must starts with a quote');
  757. start = index;
  758. ++index;
  759. while (index < length) {
  760. ch = source[index++];
  761. if (ch === quote) {
  762. quote = '';
  763. break;
  764. } else if (ch === '\\') {
  765. ch = source[index++];
  766. if (!isLineTerminator(ch)) {
  767. switch (ch) {
  768. case 'n':
  769. str += '\n';
  770. break;
  771. case 'r':
  772. str += '\r';
  773. break;
  774. case 't':
  775. str += '\t';
  776. break;
  777. case 'u':
  778. case 'x':
  779. restore = index;
  780. unescaped = scanHexEscape(ch);
  781. if (unescaped) {
  782. str += unescaped;
  783. } else {
  784. index = restore;
  785. str += ch;
  786. }
  787. break;
  788. case 'b':
  789. str += '\b';
  790. break;
  791. case 'f':
  792. str += '\f';
  793. break;
  794. case 'v':
  795. str += '\x0B';
  796. break;
  797. default:
  798. if (isOctalDigit(ch)) {
  799. code = '01234567'.indexOf(ch);
  800. // \0 is not octal escape sequence
  801. if (code !== 0) {
  802. octal = true;
  803. }
  804. if (index < length && isOctalDigit(source[index])) {
  805. octal = true;
  806. code = code * 8 + '01234567'.indexOf(source[index++]);
  807. // 3 digits are only allowed when string starts
  808. // with 0, 1, 2, 3
  809. if ('0123'.indexOf(ch) >= 0 &&
  810. index < length &&
  811. isOctalDigit(source[index])) {
  812. code = code * 8 + '01234567'.indexOf(source[index++]);
  813. }
  814. }
  815. str += String.fromCharCode(code);
  816. } else {
  817. str += ch;
  818. }
  819. break;
  820. }
  821. } else {
  822. ++lineNumber;
  823. if (ch === '\r' && source[index] === '\n') {
  824. ++index;
  825. }
  826. }
  827. } else if (isLineTerminator(ch)) {
  828. break;
  829. } else {
  830. str += ch;
  831. }
  832. }
  833. if (quote !== '') {
  834. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  835. }
  836. return {
  837. type: Token.StringLiteral,
  838. value: str,
  839. octal: octal,
  840. lineNumber: lineNumber,
  841. lineStart: lineStart,
  842. range: [start, index]
  843. };
  844. }
  845. function scanRegExp() {
  846. var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false;
  847. buffer = null;
  848. skipComment();
  849. start = index;
  850. ch = source[index];
  851. assert(ch === '/', 'Regular expression literal must start with a slash');
  852. str = source[index++];
  853. while (index < length) {
  854. ch = source[index++];
  855. str += ch;
  856. if (ch === '\\') {
  857. ch = source[index++];
  858. // ECMA-262 7.8.5
  859. if (isLineTerminator(ch)) {
  860. throwError({}, Messages.UnterminatedRegExp);
  861. }
  862. str += ch;
  863. } else if (classMarker) {
  864. if (ch === ']') {
  865. classMarker = false;
  866. }
  867. } else {
  868. if (ch === '/') {
  869. terminated = true;
  870. break;
  871. } else if (ch === '[') {
  872. classMarker = true;
  873. } else if (isLineTerminator(ch)) {
  874. throwError({}, Messages.UnterminatedRegExp);
  875. }
  876. }
  877. }
  878. if (!terminated) {
  879. throwError({}, Messages.UnterminatedRegExp);
  880. }
  881. // Exclude leading and trailing slash.
  882. pattern = str.substr(1, str.length - 2);
  883. flags = '';
  884. while (index < length) {
  885. ch = source[index];
  886. if (!isIdentifierPart(ch)) {
  887. break;
  888. }
  889. ++index;
  890. if (ch === '\\' && index < length) {
  891. ch = source[index];
  892. if (ch === 'u') {
  893. ++index;
  894. restore = index;
  895. ch = scanHexEscape('u');
  896. if (ch) {
  897. flags += ch;
  898. str += '\\u';
  899. for (; restore < index; ++restore) {
  900. str += source[restore];
  901. }
  902. } else {
  903. index = restore;
  904. flags += 'u';
  905. str += '\\u';
  906. }
  907. } else {
  908. str += '\\';
  909. }
  910. } else {
  911. flags += ch;
  912. str += ch;
  913. }
  914. }
  915. try {
  916. value = new RegExp(pattern, flags);
  917. } catch (e) {
  918. throwError({}, Messages.InvalidRegExp);
  919. }
  920. return {
  921. literal: str,
  922. value: value,
  923. range: [start, index]
  924. };
  925. }
  926. function isIdentifierName(token) {
  927. return token.type === Token.Identifier ||
  928. token.type === Token.Keyword ||
  929. token.type === Token.BooleanLiteral ||
  930. token.type === Token.NullLiteral;
  931. }
  932. function advance() {
  933. var ch, token;
  934. skipComment();
  935. if (index >= length) {
  936. return {
  937. type: Token.EOF,
  938. lineNumber: lineNumber,
  939. lineStart: lineStart,
  940. range: [index, index]
  941. };
  942. }
  943. token = scanPunctuator();
  944. if (typeof token !== 'undefined') {
  945. return token;
  946. }
  947. ch = source[index];
  948. if (ch === '\'' || ch === '"') {
  949. return scanStringLiteral();
  950. }
  951. if (ch === '.' || isDecimalDigit(ch)) {
  952. return scanNumericLiteral();
  953. }
  954. token = scanIdentifier();
  955. if (typeof token !== 'undefined') {
  956. return token;
  957. }
  958. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  959. }
  960. function lex() {
  961. var token;
  962. if (buffer) {
  963. index = buffer.range[1];
  964. lineNumber = buffer.lineNumber;
  965. lineStart = buffer.lineStart;
  966. token = buffer;
  967. buffer = null;
  968. return token;
  969. }
  970. buffer = null;
  971. return advance();
  972. }
  973. function lookahead() {
  974. var pos, line, start;
  975. if (buffer !== null) {
  976. return buffer;
  977. }
  978. pos = index;
  979. line = lineNumber;
  980. start = lineStart;
  981. buffer = advance();
  982. index = pos;
  983. lineNumber = line;
  984. lineStart = start;
  985. return buffer;
  986. }
  987. // Return true if there is a line terminator before the next token.
  988. function peekLineTerminator() {
  989. var pos, line, start, found;
  990. pos = index;
  991. line = lineNumber;
  992. start = lineStart;
  993. skipComment();
  994. found = lineNumber !== line;
  995. index = pos;
  996. lineNumber = line;
  997. lineStart = start;
  998. return found;
  999. }
  1000. // Throw an exception
  1001. function throwError(token, messageFormat) {
  1002. var error,
  1003. args = Array.prototype.slice.call(arguments, 2),
  1004. msg = messageFormat.replace(
  1005. /%(\d)/g,
  1006. function (whole, index) {
  1007. return args[index] || '';
  1008. }
  1009. );
  1010. if (typeof token.lineNumber === 'number') {
  1011. error = new Error('Line ' + token.lineNumber + ': ' + msg);
  1012. error.index = token.range[0];
  1013. error.lineNumber = token.lineNumber;
  1014. error.column = token.range[0] - lineStart + 1;
  1015. } else {
  1016. error = new Error('Line ' + lineNumber + ': ' + msg);
  1017. error.index = index;
  1018. error.lineNumber = lineNumber;
  1019. error.column = index - lineStart + 1;
  1020. }
  1021. throw error;
  1022. }
  1023. function throwErrorTolerant() {
  1024. try {
  1025. throwError.apply(null, arguments);
  1026. } catch (e) {
  1027. if (extra.errors) {
  1028. extra.errors.push(e);
  1029. } else {
  1030. throw e;
  1031. }
  1032. }
  1033. }
  1034. // Throw an exception because of the token.
  1035. function throwUnexpected(token) {
  1036. if (token.type === Token.EOF) {
  1037. throwError(token, Messages.UnexpectedEOS);
  1038. }
  1039. if (token.type === Token.NumericLiteral) {
  1040. throwError(token, Messages.UnexpectedNumber);
  1041. }
  1042. if (token.type === Token.StringLiteral) {
  1043. throwError(token, Messages.UnexpectedString);
  1044. }
  1045. if (token.type === Token.Identifier) {
  1046. throwError(token, Messages.UnexpectedIdentifier);
  1047. }
  1048. if (token.type === Token.Keyword) {
  1049. if (isFutureReservedWord(token.value)) {
  1050. throwError(token, Messages.UnexpectedReserved);
  1051. } else if (strict && isStrictModeReservedWord(token.value)) {
  1052. throwErrorTolerant(token, Messages.StrictReservedWord);
  1053. return;
  1054. }
  1055. throwError(token, Messages.UnexpectedToken, token.value);
  1056. }
  1057. // BooleanLiteral, NullLiteral, or Punctuator.
  1058. throwError(token, Messages.UnexpectedToken, token.value);
  1059. }
  1060. // Expect the next token to match the specified punctuator.
  1061. // If not, an exception will be thrown.
  1062. function expect(value) {
  1063. var token = lex();
  1064. if (token.type !== Token.Punctuator || token.value !== value) {
  1065. throwUnexpected(token);
  1066. }
  1067. }
  1068. // Expect the next token to match the specified keyword.
  1069. // If not, an exception will be thrown.
  1070. function expectKeyword(keyword) {
  1071. var token = lex();
  1072. if (token.type !== Token.Keyword || token.value !== keyword) {
  1073. throwUnexpected(token);
  1074. }
  1075. }
  1076. // Return true if the next token matches the specified punctuator.
  1077. function match(value) {
  1078. var token = lookahead();
  1079. return token.type === Token.Punctuator && token.value === value;
  1080. }
  1081. // Return true if the next token matches the specified keyword
  1082. function matchKeyword(keyword) {
  1083. var token = lookahead();
  1084. return token.type === Token.Keyword && token.value === keyword;
  1085. }
  1086. // Return true if the next token is an assignment operator
  1087. function matchAssign() {
  1088. var token = lookahead(),
  1089. op = token.value;
  1090. if (token.type !== Token.Punctuator) {
  1091. return false;
  1092. }
  1093. return op === '=' ||
  1094. op === '*=' ||
  1095. op === '/=' ||
  1096. op === '%=' ||
  1097. op === '+=' ||
  1098. op === '-=' ||
  1099. op === '<<=' ||
  1100. op === '>>=' ||
  1101. op === '>>>=' ||
  1102. op === '&=' ||
  1103. op === '^=' ||
  1104. op === '|=';
  1105. }
  1106. function consumeSemicolon() {
  1107. var token, line;
  1108. // Catch the very common case first.
  1109. if (source[index] === ';') {
  1110. lex();
  1111. return;
  1112. }
  1113. line = lineNumber;
  1114. skipComment();
  1115. if (lineNumber !== line) {
  1116. return;
  1117. }
  1118. if (match(';')) {
  1119. lex();
  1120. return;
  1121. }
  1122. token = lookahead();
  1123. if (token.type !== Token.EOF && !match('}')) {
  1124. throwUnexpected(token);
  1125. }
  1126. }
  1127. // Return true if provided expression is LeftHandSideExpression
  1128. function isLeftHandSide(expr) {
  1129. return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
  1130. }
  1131. // 11.1.4 Array Initialiser
  1132. function parseArrayInitialiser() {
  1133. var elements = [];
  1134. expect('[');
  1135. while (!match(']')) {
  1136. if (match(',')) {
  1137. lex();
  1138. elements.push(null);
  1139. } else {
  1140. elements.push(parseAssignmentExpression());
  1141. if (!match(']')) {
  1142. expect(',');
  1143. }
  1144. }
  1145. }
  1146. expect(']');
  1147. return {
  1148. type: Syntax.ArrayExpression,
  1149. elements: elements
  1150. };
  1151. }
  1152. // 11.1.5 Object Initialiser
  1153. function parsePropertyFunction(param, first) {
  1154. var previousStrict, body;
  1155. previousStrict = strict;
  1156. body = parseFunctionSourceElements();
  1157. if (first && strict && isRestrictedWord(param[0].name)) {
  1158. throwErrorTolerant(first, Messages.StrictParamName);
  1159. }
  1160. strict = previousStrict;
  1161. return {
  1162. type: Syntax.FunctionExpression,
  1163. id: null,
  1164. params: param,
  1165. defaults: [],
  1166. body: body,
  1167. rest: null,
  1168. generator: false,
  1169. expression: false
  1170. };
  1171. }
  1172. function parseObjectPropertyKey() {
  1173. var token = lex();
  1174. // Note: This function is called only from parseObjectProperty(), where
  1175. // EOF and Punctuator tokens are already filtered out.
  1176. if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
  1177. if (strict && token.octal) {
  1178. throwErrorTolerant(token, Messages.StrictOctalLiteral);
  1179. }
  1180. return createLiteral(token);
  1181. }
  1182. return {
  1183. type: Syntax.Identifier,
  1184. name: token.value
  1185. };
  1186. }
  1187. function parseObjectProperty() {
  1188. var token, key, id, param;
  1189. token = lookahead();
  1190. if (token.type === Token.Identifier) {
  1191. id = parseObjectPropertyKey();
  1192. // Property Assignment: Getter and Setter.
  1193. if (token.value === 'get' && !match(':')) {
  1194. key = parseObjectPropertyKey();
  1195. expect('(');
  1196. expect(')');
  1197. return {
  1198. type: Syntax.Property,
  1199. key: key,
  1200. value: parsePropertyFunction([]),
  1201. kind: 'get'
  1202. };
  1203. } else if (token.value === 'set' && !match(':')) {
  1204. key = parseObjectPropertyKey();
  1205. expect('(');
  1206. token = lookahead();
  1207. if (token.type !== Token.Identifier) {
  1208. expect(')');
  1209. throwErrorTolerant(token, Messages.UnexpectedToken, token.value);
  1210. return {
  1211. type: Syntax.Property,
  1212. key: key,
  1213. value: parsePropertyFunction([]),
  1214. kind: 'set'
  1215. };
  1216. } else {
  1217. param = [ parseVariableIdentifier() ];
  1218. expect(')');
  1219. return {
  1220. type: Syntax.Property,
  1221. key: key,
  1222. value: parsePropertyFunction(param, token),
  1223. kind: 'set'
  1224. };
  1225. }
  1226. } else {
  1227. expect(':');
  1228. return {
  1229. type: Syntax.Property,
  1230. key: id,
  1231. value: parseAssignmentExpression(),
  1232. kind: 'init'
  1233. };
  1234. }
  1235. } else if (token.type === Token.EOF || token.type === Token.Punctuator) {
  1236. throwUnexpected(token);
  1237. } else {
  1238. key = parseObjectPropertyKey();
  1239. expect(':');
  1240. return {
  1241. type: Syntax.Property,
  1242. key: key,
  1243. value: parseAssignmentExpression(),
  1244. kind: 'init'
  1245. };
  1246. }
  1247. }
  1248. function parseObjectInitialiser() {
  1249. var properties = [], property, name, kind, map = {}, toString = String;
  1250. expect('{');
  1251. while (!match('}')) {
  1252. property = parseObjectProperty();
  1253. if (property.key.type === Syntax.Identifier) {
  1254. name = property.key.name;
  1255. } else {
  1256. name = toString(property.key.value);
  1257. }
  1258. kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
  1259. if (Object.prototype.hasOwnProperty.call(map, name)) {
  1260. if (map[name] === PropertyKind.Data) {
  1261. if (strict && kind === PropertyKind.Data) {
  1262. throwErrorTolerant({}, Messages.StrictDuplicateProperty);
  1263. } else if (kind !== PropertyKind.Data) {
  1264. throwErrorTolerant({}, Messages.AccessorDataProperty);
  1265. }
  1266. } else {
  1267. if (kind === PropertyKind.Data) {
  1268. throwErrorTolerant({}, Messages.AccessorDataProperty);
  1269. } else if (map[name] & kind) {
  1270. throwErrorTolerant({}, Messages.AccessorGetSet);
  1271. }
  1272. }
  1273. map[name] |= kind;
  1274. } else {
  1275. map[name] = kind;
  1276. }
  1277. properties.push(property);
  1278. if (!match('}')) {
  1279. expect(',');
  1280. }
  1281. }
  1282. expect('}');
  1283. return {
  1284. type: Syntax.ObjectExpression,
  1285. properties: properties
  1286. };
  1287. }
  1288. // 11.1.6 The Grouping Operator
  1289. function parseGroupExpression() {
  1290. var expr;
  1291. expect('(');
  1292. expr = parseExpression();
  1293. expect(')');
  1294. return expr;
  1295. }
  1296. // 11.1 Primary Expressions
  1297. function parsePrimaryExpression() {
  1298. var token = lookahead(),
  1299. type = token.type;
  1300. if (type === Token.Identifier) {
  1301. return {
  1302. type: Syntax.Identifier,
  1303. name: lex().value
  1304. };
  1305. }
  1306. if (type === Token.StringLiteral || type === Token.NumericLiteral) {
  1307. if (strict && token.octal) {
  1308. throwErrorTolerant(token, Messages.StrictOctalLiteral);
  1309. }
  1310. return createLiteral(lex());
  1311. }
  1312. if (type === Token.Keyword) {
  1313. if (matchKeyword('this')) {
  1314. lex();
  1315. return {
  1316. type: Syntax.ThisExpression
  1317. };
  1318. }
  1319. if (matchKeyword('function')) {
  1320. return parseFunctionExpression();
  1321. }
  1322. }
  1323. if (type === Token.BooleanLiteral) {
  1324. lex();
  1325. token.value = (token.value === 'true');
  1326. return createLiteral(token);
  1327. }
  1328. if (type === Token.NullLiteral) {
  1329. lex();
  1330. token.value = null;
  1331. return createLiteral(token);
  1332. }
  1333. if (match('[')) {
  1334. return parseArrayInitialiser();
  1335. }
  1336. if (match('{')) {
  1337. return parseObjectInitialiser();
  1338. }
  1339. if (match('(')) {
  1340. return parseGroupExpression();
  1341. }
  1342. if (match('/') || match('/=')) {
  1343. return createLiteral(scanRegExp());
  1344. }
  1345. return throwUnexpected(lex());
  1346. }
  1347. // 11.2 Left-Hand-Side Expressions
  1348. function parseArguments() {
  1349. var args = [];
  1350. expect('(');
  1351. if (!match(')')) {
  1352. while (index < length) {
  1353. args.push(parseAssignmentExpression());
  1354. if (match(')')) {
  1355. break;
  1356. }
  1357. expect(',');
  1358. }
  1359. }
  1360. expect(')');
  1361. return args;
  1362. }
  1363. function parseNonComputedProperty() {
  1364. var token = lex();
  1365. if (!isIdentifierName(token)) {
  1366. throwUnexpected(token);
  1367. }
  1368. return {
  1369. type: Syntax.Identifier,
  1370. name: token.value
  1371. };
  1372. }
  1373. function parseNonComputedMember() {
  1374. expect('.');
  1375. return parseNonComputedProperty();
  1376. }
  1377. function parseComputedMember() {
  1378. var expr;
  1379. expect('[');
  1380. expr = parseExpression();
  1381. expect(']');
  1382. return expr;
  1383. }
  1384. function parseNewExpression() {
  1385. var expr;
  1386. expectKeyword('new');
  1387. expr = {
  1388. type: Syntax.NewExpression,
  1389. callee: parseLeftHandSideExpression(),
  1390. 'arguments': []
  1391. };
  1392. if (match('(')) {
  1393. expr['arguments'] = parseArguments();
  1394. }
  1395. return expr;
  1396. }
  1397. function parseLeftHandSideExpressionAllowCall() {
  1398. var expr;
  1399. expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
  1400. while (match('.') || match('[') || match('(')) {
  1401. if (match('(')) {
  1402. expr = {
  1403. type: Syntax.CallExpression,
  1404. callee: expr,
  1405. 'arguments': parseArguments()
  1406. };
  1407. } else if (match('[')) {
  1408. expr = {
  1409. type: Syntax.MemberExpression,
  1410. computed: true,
  1411. object: expr,
  1412. property: parseComputedMember()
  1413. };
  1414. } else {
  1415. expr = {
  1416. type: Syntax.MemberExpression,
  1417. computed: false,
  1418. object: expr,
  1419. property: parseNonComputedMember()
  1420. };
  1421. }
  1422. }
  1423. return expr;
  1424. }
  1425. function parseLeftHandSideExpression() {
  1426. var expr;
  1427. expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
  1428. while (match('.') || match('[')) {
  1429. if (match('[')) {
  1430. expr = {
  1431. type: Syntax.MemberExpression,
  1432. computed: true,
  1433. object: expr,
  1434. property: parseComputedMember()
  1435. };
  1436. } else {
  1437. expr = {
  1438. type: Syntax.MemberExpression,
  1439. computed: false,
  1440. object: expr,
  1441. property: parseNonComputedMember()
  1442. };
  1443. }
  1444. }
  1445. return expr;
  1446. }
  1447. // 11.3 Postfix Expressions
  1448. function parsePostfixExpression() {
  1449. var expr = parseLeftHandSideExpressionAllowCall(), token;
  1450. token = lookahead();
  1451. if (token.type !== Token.Punctuator) {
  1452. return expr;
  1453. }
  1454. if ((match('++') || match('--')) && !peekLineTerminator()) {
  1455. // 11.3.1, 11.3.2
  1456. if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
  1457. throwErrorTolerant({}, Messages.StrictLHSPostfix);
  1458. }
  1459. if (!isLeftHandSide(expr)) {
  1460. throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
  1461. }
  1462. expr = {
  1463. type: Syntax.UpdateExpression,
  1464. operator: lex().value,
  1465. argument: expr,
  1466. prefix: false
  1467. };
  1468. }
  1469. return expr;
  1470. }
  1471. // 11.4 Unary Operators
  1472. function parseUnaryExpression() {
  1473. var token, expr;
  1474. token = lookahead();
  1475. if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
  1476. return parsePostfixExpression();
  1477. }
  1478. if (match('++') || match('--')) {
  1479. token = lex();
  1480. expr = parseUnaryExpression();
  1481. // 11.4.4, 11.4.5
  1482. if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
  1483. throwErrorTolerant({}, Messages.StrictLHSPrefix);
  1484. }
  1485. if (!isLeftHandSide(expr)) {
  1486. throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
  1487. }
  1488. expr = {
  1489. type: Syntax.UpdateExpression,
  1490. operator: token.value,
  1491. argument: expr,
  1492. prefix: true
  1493. };
  1494. return expr;
  1495. }
  1496. if (match('+') || match('-') || match('~') || match('!')) {
  1497. expr = {
  1498. type: Syntax.UnaryExpression,
  1499. operator: lex().value,
  1500. argument: parseUnaryExpression(),
  1501. prefix: true
  1502. };
  1503. return expr;
  1504. }
  1505. if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
  1506. expr = {
  1507. type: Syntax.UnaryExpression,
  1508. operator: lex().value,
  1509. argument: parseUnaryExpression(),
  1510. prefix: true
  1511. };
  1512. if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
  1513. throwErrorTolerant({}, Messages.StrictDelete);
  1514. }
  1515. return expr;
  1516. }
  1517. return parsePostfixExpression();
  1518. }
  1519. // 11.5 Multiplicative Operators
  1520. function parseMultiplicativeExpression() {
  1521. var expr = parseUnaryExpression();
  1522. while (match('*') || match('/') || match('%')) {
  1523. expr = {
  1524. type: Syntax.BinaryExpression,
  1525. operator: lex().value,
  1526. left: expr,
  1527. right: parseUnaryExpression()
  1528. };
  1529. }
  1530. return expr;
  1531. }
  1532. // 11.6 Additive Operators
  1533. function parseAdditiveExpression() {
  1534. var expr = parseMultiplicativeExpression();
  1535. while (match('+') || match('-')) {
  1536. expr = {
  1537. type: Syntax.BinaryExpression,
  1538. operator: lex().value,
  1539. left: expr,
  1540. right: parseMultiplicativeExpression()
  1541. };
  1542. }
  1543. return expr;
  1544. }
  1545. // 11.7 Bitwise Shift Operators
  1546. function parseShiftExpression() {
  1547. var expr = parseAdditiveExpression();
  1548. while (match('<<') || match('>>') || match('>>>')) {
  1549. expr = {
  1550. type: Syntax.BinaryExpression,
  1551. operator: lex().value,
  1552. left: expr,
  1553. right: parseAdditiveExpression()
  1554. };
  1555. }
  1556. return expr;
  1557. }
  1558. // 11.8 Relational Operators
  1559. function parseRelationalExpression() {
  1560. var expr, previousAllowIn;
  1561. previousAllowIn = state.allowIn;
  1562. state.allowIn = true;
  1563. expr = parseShiftExpression();
  1564. while (match('<') || match('>') || match('<=') || match('>=') || (previousAllowIn && matchKeyword('in')) || matchKeyword('instanceof')) {
  1565. expr = {
  1566. type: Syntax.BinaryExpression,
  1567. operator: lex().value,
  1568. left: expr,
  1569. right: parseShiftExpression()
  1570. };
  1571. }
  1572. state.allowIn = previousAllowIn;
  1573. return expr;
  1574. }
  1575. // 11.9 Equality Operators
  1576. function parseEqualityExpression() {
  1577. var expr = parseRelationalExpression();
  1578. while (match('==') || match('!=') || match('===') || match('!==')) {
  1579. expr = {
  1580. type: Syntax.BinaryExpression,
  1581. operator: lex().value,
  1582. left: expr,
  1583. right: parseRelationalExpression()
  1584. };
  1585. }
  1586. return expr;
  1587. }
  1588. // 11.10 Binary Bitwise Operators
  1589. function parseBitwiseANDExpression() {
  1590. var expr = parseEqualityExpression();
  1591. while (match('&')) {
  1592. lex();
  1593. expr = {
  1594. type: Syntax.BinaryExpression,
  1595. operator: '&',
  1596. left: expr,
  1597. right: parseEqualityExpression()
  1598. };
  1599. }
  1600. return expr;
  1601. }
  1602. function parseBitwiseXORExpression() {
  1603. var expr = parseBitwiseANDExpression();
  1604. while (match('^')) {
  1605. lex();
  1606. expr = {
  1607. type: Syntax.BinaryExpression,
  1608. operator: '^',
  1609. left: expr,
  1610. right: parseBitwiseANDExpression()
  1611. };
  1612. }
  1613. return expr;
  1614. }
  1615. function parseBitwiseORExpression() {
  1616. var expr = parseBitwiseXORExpression();
  1617. while (match('|')) {
  1618. lex();
  1619. expr = {
  1620. type: Syntax.BinaryExpression,
  1621. operator: '|',
  1622. left: expr,
  1623. right: parseBitwiseXORExpression()
  1624. };
  1625. }
  1626. return expr;
  1627. }
  1628. // 11.11 Binary Logical Operators
  1629. function parseLogicalANDExpression() {
  1630. var expr = parseBitwiseORExpression();
  1631. while (match('&&')) {
  1632. lex();
  1633. expr = {
  1634. type: Syntax.LogicalExpression,
  1635. operator: '&&',
  1636. left: expr,
  1637. right: parseBitwiseORExpression()
  1638. };
  1639. }
  1640. return expr;
  1641. }
  1642. function parseLogicalORExpression() {
  1643. var expr = parseLogicalANDExpression();
  1644. while (match('||')) {
  1645. lex();
  1646. expr = {
  1647. type: Syntax.LogicalExpression,
  1648. operator: '||',
  1649. left: expr,
  1650. right: parseLogicalANDExpression()
  1651. };
  1652. }
  1653. return expr;
  1654. }
  1655. // 11.12 Conditional Operator
  1656. function parseConditionalExpression() {
  1657. var expr, previousAllowIn, consequent;
  1658. expr = parseLogicalORExpression();
  1659. if (match('?')) {
  1660. lex();
  1661. previousAllowIn = state.allowIn;
  1662. state.allowIn = true;
  1663. consequent = parseAssignmentExpression();
  1664. state.allowIn = previousAllowIn;
  1665. expect(':');
  1666. expr = {
  1667. type: Syntax.ConditionalExpression,
  1668. test: expr,
  1669. consequent: consequent,
  1670. alternate: parseAssignmentExpression()
  1671. };
  1672. }
  1673. return expr;
  1674. }
  1675. // 11.13 Assignment Operators
  1676. function parseAssignmentExpression() {
  1677. var token, expr;
  1678. token = lookahead();
  1679. expr = parseConditionalExpression();
  1680. if (matchAssign()) {
  1681. // LeftHandSideExpression
  1682. if (!isLeftHandSide(expr)) {
  1683. throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
  1684. }
  1685. // 11.13.1
  1686. if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
  1687. throwErrorTolerant(token, Messages.StrictLHSAssignment);
  1688. }
  1689. expr = {
  1690. type: Syntax.AssignmentExpression,
  1691. operator: lex().value,
  1692. left: expr,
  1693. right: parseAssignmentExpression()
  1694. };
  1695. }
  1696. return expr;
  1697. }
  1698. // 11.14 Comma Operator
  1699. function parseExpression() {
  1700. var expr = parseAssignmentExpression();
  1701. if (match(',')) {
  1702. expr = {
  1703. type: Syntax.SequenceExpression,
  1704. expressions: [ expr ]
  1705. };
  1706. while (index < length) {
  1707. if (!match(',')) {
  1708. break;
  1709. }
  1710. lex();
  1711. expr.expressions.push(parseAssignmentExpression());
  1712. }
  1713. }
  1714. return expr;
  1715. }
  1716. // 12.1 Block
  1717. function parseStatementList() {
  1718. var list = [],
  1719. statement;
  1720. while (index < length) {
  1721. if (match('}')) {
  1722. break;
  1723. }
  1724. statement = parseSourceElement();
  1725. if (typeof statement === 'undefined') {
  1726. break;
  1727. }
  1728. list.push(statement);
  1729. }
  1730. return list;
  1731. }
  1732. function parseBlock() {
  1733. var block;
  1734. expect('{');
  1735. block = parseStatementList();
  1736. expect('}');
  1737. return {
  1738. type: Syntax.BlockStatement,
  1739. body: block
  1740. };
  1741. }
  1742. // 12.2 Variable Statement
  1743. function parseVariableIdentifier() {
  1744. var token = lex();
  1745. if (token.type !== Token.Identifier) {
  1746. throwUnexpected(token);
  1747. }
  1748. return {
  1749. type: Syntax.Identifier,
  1750. name: token.value
  1751. };
  1752. }
  1753. function parseVariableDeclaration(kind) {
  1754. var id = parseVariableIdentifier(),
  1755. init = null;
  1756. // 12.2.1
  1757. if (strict && isRestrictedWord(id.name)) {
  1758. throwErrorTolerant({}, Messages.StrictVarName);
  1759. }
  1760. if (kind === 'const') {
  1761. expect('=');
  1762. init = parseAssignmentExpression();
  1763. } else if (match('=')) {
  1764. lex();
  1765. init = parseAssignmentExpression();
  1766. }
  1767. return {
  1768. type: Syntax.VariableDeclarator,
  1769. id: id,
  1770. init: init
  1771. };
  1772. }
  1773. function parseVariableDeclarationList(kind) {
  1774. var list = [];
  1775. do {
  1776. list.push(parseVariableDeclaration(kind));
  1777. if (!match(',')) {
  1778. break;
  1779. }
  1780. lex();
  1781. } while (index < length);
  1782. return list;
  1783. }
  1784. function parseVariableStatement() {
  1785. var declarations;
  1786. expectKeyword('var');
  1787. declarations = parseVariableDeclarationList();
  1788. consumeSemicolon();
  1789. return {
  1790. type: Syntax.VariableDeclaration,
  1791. declarations: declarations,
  1792. kind: 'var'
  1793. };
  1794. }
  1795. // kind may be `const` or `let`
  1796. // Both are experimental and not in the specification yet.
  1797. // see http://wiki.ecmascript.org/doku.php?id=harmony:const
  1798. // and http://wiki.ecmascript.org/doku.php?id=harmony:let
  1799. function parseConstLetDeclaration(kind) {
  1800. var declarations;
  1801. expectKeyword(kind);
  1802. declarations = parseVariableDeclarationList(kind);
  1803. consumeSemicolon();
  1804. return {
  1805. type: Syntax.VariableDeclaration,
  1806. declarations: declarations,
  1807. kind: kind
  1808. };
  1809. }
  1810. // 12.3 Empty Statement
  1811. function parseEmptyStatement() {
  1812. expect(';');
  1813. return {
  1814. type: Syntax.EmptyStatement
  1815. };
  1816. }
  1817. // 12.4 Expression Statement
  1818. function parseExpressionStatement() {
  1819. var expr = parseExpression();
  1820. consumeSemicolon();
  1821. return {
  1822. type: Syntax.ExpressionStatement,
  1823. expression: expr
  1824. };
  1825. }
  1826. // 12.5 If statement
  1827. function parseIfStatement() {
  1828. var test, consequent, alternate;
  1829. expectKeyword('if');
  1830. expect('(');
  1831. test = parseExpression();
  1832. expect(')');
  1833. consequent = parseStatement();
  1834. if (matchKeyword('else')) {
  1835. lex();
  1836. alternate = parseStatement();
  1837. } else {
  1838. alternate = null;
  1839. }
  1840. return {
  1841. type: Syntax.IfStatement,
  1842. test: test,
  1843. consequent: consequent,
  1844. alternate: alternate
  1845. };
  1846. }
  1847. // 12.6 Iteration Statements
  1848. function parseDoWhileStatement() {
  1849. var body, test, oldInIteration;
  1850. expectKeyword('do');
  1851. oldInIteration = state.inIteration;
  1852. state.inIteration = true;
  1853. body = parseStatement();
  1854. state.inIteration = oldInIteration;
  1855. expectKeyword('while');
  1856. expect('(');
  1857. test = parseExpression();
  1858. expect(')');
  1859. if (match(';')) {
  1860. lex();
  1861. }
  1862. return {
  1863. type: Syntax.DoWhileStatement,
  1864. body: body,
  1865. test: test
  1866. };
  1867. }
  1868. function parseWhileStatement() {
  1869. var test, body, oldInIteration;
  1870. expectKeyword('while');
  1871. expect('(');
  1872. test = parseExpression();
  1873. expect(')');
  1874. oldInIteration = state.inIteration;
  1875. state.inIteration = true;
  1876. body = parseStatement();
  1877. state.inIteration = oldInIteration;
  1878. return {
  1879. type: Syntax.WhileStatement,
  1880. test: test,
  1881. body: body
  1882. };
  1883. }
  1884. function parseForVariableDeclaration() {
  1885. var token = lex();
  1886. return {
  1887. type: Syntax.VariableDeclaration,
  1888. declarations: parseVariableDeclarationList(),
  1889. kind: token.value
  1890. };
  1891. }
  1892. function parseForStatement() {
  1893. var init, test, update, left, right, body, oldInIteration;
  1894. init = test = update = null;
  1895. expectKeyword('for');
  1896. expect('(');
  1897. if (match(';')) {
  1898. lex();
  1899. } else {
  1900. if (matchKeyword('var') || matchKeyword('let')) {
  1901. state.allowIn = false;
  1902. init = parseForVariableDeclaration();
  1903. state.allowIn = true;
  1904. if (init.declarations.length === 1 && matchKeyword('in')) {
  1905. lex();
  1906. left = init;
  1907. right = parseExpression();
  1908. init = null;
  1909. }
  1910. } else {
  1911. state.allowIn = false;
  1912. init = parseExpression();
  1913. state.allowIn = true;
  1914. if (matchKeyword('in')) {
  1915. // LeftHandSideExpression
  1916. if (!isLeftHandSide(init)) {
  1917. throwErrorTolerant({}, Messages.InvalidLHSInForIn);
  1918. }
  1919. lex();
  1920. left = init;
  1921. right = parseExpression();
  1922. init = null;
  1923. }
  1924. }
  1925. if (typeof left === 'undefined') {
  1926. expect(';');
  1927. }
  1928. }
  1929. if (typeof left === 'undefined') {
  1930. if (!match(';')) {
  1931. test = parseExpression();
  1932. }
  1933. expect(';');
  1934. if (!match(')')) {
  1935. update = parseExpression();
  1936. }
  1937. }
  1938. expect(')');
  1939. oldInIteration = state.inIteration;
  1940. state.inIteration = true;
  1941. body = parseStatement();
  1942. state.inIteration = oldInIteration;
  1943. if (typeof left === 'undefined') {
  1944. return {
  1945. type: Syntax.ForStatement,
  1946. init: init,
  1947. test: test,
  1948. update: update,
  1949. body: body
  1950. };
  1951. }
  1952. return {
  1953. type: Syntax.ForInStatement,
  1954. left: left,
  1955. right: right,
  1956. body: body,
  1957. each: false
  1958. };
  1959. }
  1960. // 12.7 The continue statement
  1961. function parseContinueStatement() {
  1962. var token, label = null;
  1963. expectKeyword('continue');
  1964. // Optimize the most common form: 'continue;'.
  1965. if (source[index] === ';') {
  1966. lex();
  1967. if (!state.inIteration) {
  1968. throwError({}, Messages.IllegalContinue);
  1969. }
  1970. return {
  1971. type: Syntax.ContinueStatement,
  1972. label: null
  1973. };
  1974. }
  1975. if (peekLineTerminator()) {
  1976. if (!state.inIteration) {
  1977. throwError({}, Messages.IllegalContinue);
  1978. }
  1979. return {
  1980. type: Syntax.ContinueStatement,
  1981. label: null
  1982. };
  1983. }
  1984. token = lookahead();
  1985. if (token.type === Token.Identifier) {
  1986. label = parseVariableIdentifier();
  1987. if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) {
  1988. throwError({}, Messages.UnknownLabel, label.name);
  1989. }
  1990. }
  1991. consumeSemicolon();
  1992. if (label === null && !state.inIteration) {
  1993. throwError({}, Messages.IllegalContinue);
  1994. }
  1995. return {
  1996. type: Syntax.ContinueStatement,
  1997. label: label
  1998. };
  1999. }
  2000. // 12.8 The break statement
  2001. function parseBreakStatement() {
  2002. var token, label = null;
  2003. expectKeyword('break');
  2004. // Optimize the most common form: 'break;'.
  2005. if (source[index] === ';') {
  2006. lex();
  2007. if (!(state.inIteration || state.inSwitch)) {
  2008. throwError({}, Messages.IllegalBreak);
  2009. }
  2010. return {
  2011. type: Syntax.BreakStatement,
  2012. label: null
  2013. };
  2014. }
  2015. if (peekLineTerminator()) {
  2016. if (!(state.inIteration || state.inSwitch)) {
  2017. throwError({}, Messages.IllegalBreak);
  2018. }
  2019. return {
  2020. type: Syntax.BreakStatement,
  2021. label: null
  2022. };
  2023. }
  2024. token = lookahead();
  2025. if (token.type === Token.Identifier) {
  2026. label = parseVariableIdentifier();
  2027. if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) {
  2028. throwError({}, Messages.UnknownLabel, label.name);
  2029. }
  2030. }
  2031. consumeSemicolon();
  2032. if (label === null && !(state.inIteration || state.inSwitch)) {
  2033. throwError({}, Messages.IllegalBreak);
  2034. }
  2035. return {
  2036. type: Syntax.BreakStatement,
  2037. label: label
  2038. };
  2039. }
  2040. // 12.9 The return statement
  2041. function parseReturnStatement() {
  2042. var token, argument = null;
  2043. expectKeyword('return');
  2044. if (!state.inFunctionBody) {
  2045. throwErrorTolerant({}, Messages.IllegalReturn);
  2046. }
  2047. // 'return' followed by a space and an identifier is very common.
  2048. if (source[index] === ' ') {
  2049. if (isIdentifierStart(source[index + 1])) {
  2050. argument = parseExpression();
  2051. consumeSemicolon();
  2052. return {
  2053. type: Syntax.ReturnStatement,
  2054. argument: argument
  2055. };
  2056. }
  2057. }
  2058. if (peekLineTerminator()) {
  2059. return {
  2060. type: Syntax.ReturnStatement,
  2061. argument: null
  2062. };
  2063. }
  2064. if (!match(';')) {
  2065. token = lookahead();
  2066. if (!match('}') && token.type !== Token.EOF) {
  2067. argument = parseExpression();
  2068. }
  2069. }
  2070. consumeSemicolon();
  2071. return {
  2072. type: Syntax.ReturnStatement,
  2073. argument: argument
  2074. };
  2075. }
  2076. // 12.10 The with statement
  2077. function parseWithStatement() {
  2078. var object, body;
  2079. if (strict) {
  2080. throwErrorTolerant({}, Messages.StrictModeWith);
  2081. }
  2082. expectKeyword('with');
  2083. expect('(');
  2084. object = parseExpression();
  2085. expect(')');
  2086. body = parseStatement();
  2087. return {
  2088. type: Syntax.WithStatement,
  2089. object: object,
  2090. body: body
  2091. };
  2092. }
  2093. // 12.10 The swith statement
  2094. function parseSwitchCase() {
  2095. var test,
  2096. consequent = [],
  2097. statement;
  2098. if (matchKeyword('default')) {
  2099. lex();
  2100. test = null;
  2101. } else {
  2102. expectKeyword('case');
  2103. test = parseExpression();
  2104. }
  2105. expect(':');
  2106. while (index < length) {
  2107. if (match('}') || matchKeyword('default') || matchKeyword('case')) {
  2108. break;
  2109. }
  2110. statement = parseStatement();
  2111. if (typeof statement === 'undefined') {
  2112. break;
  2113. }
  2114. consequent.push(statement);
  2115. }
  2116. return {
  2117. type: Syntax.SwitchCase,
  2118. test: test,
  2119. consequent: consequent
  2120. };
  2121. }
  2122. function parseSwitchStatement() {
  2123. var discriminant, cases, clause, oldInSwitch, defaultFound;
  2124. expectKeyword('switch');
  2125. expect('(');
  2126. discriminant = parseExpression();
  2127. expect(')');
  2128. expect('{');
  2129. cases = [];
  2130. if (match('}')) {
  2131. lex();
  2132. return {
  2133. type: Syntax.SwitchStatement,
  2134. discriminant: discriminant,
  2135. cases: cases
  2136. };
  2137. }
  2138. oldInSwitch = state.inSwitch;
  2139. state.inSwitch = true;
  2140. defaultFound = false;
  2141. while (index < length) {
  2142. if (match('}')) {
  2143. break;
  2144. }
  2145. clause = parseSwitchCase();
  2146. if (clause.test === null) {
  2147. if (defaultFound) {
  2148. throwError({}, Messages.MultipleDefaultsInSwitch);
  2149. }
  2150. defaultFound = true;
  2151. }
  2152. cases.push(clause);
  2153. }
  2154. state.inSwitch = oldInSwitch;
  2155. expect('}');
  2156. return {
  2157. type: Syntax.SwitchStatement,
  2158. discriminant: discriminant,
  2159. cases: cases
  2160. };
  2161. }
  2162. // 12.13 The throw statement
  2163. function parseThrowStatement() {
  2164. var argument;
  2165. expectKeyword('throw');
  2166. if (peekLineTerminator()) {
  2167. throwError({}, Messages.NewlineAfterThrow);
  2168. }
  2169. argument = parseExpression();
  2170. consumeSemicolon();
  2171. return {
  2172. type: Syntax.ThrowStatement,
  2173. argument: argument
  2174. };
  2175. }
  2176. // 12.14 The try statement
  2177. function parseCatchClause() {
  2178. var param;
  2179. expectKeyword('catch');
  2180. expect('(');
  2181. if (match(')')) {
  2182. throwUnexpected(lookahead());
  2183. }
  2184. param = parseVariableIdentifier();
  2185. // 12.14.1
  2186. if (strict && isRestrictedWord(param.name)) {
  2187. throwErrorTolerant({}, Messages.StrictCatchVariable);
  2188. }
  2189. expect(')');
  2190. return {
  2191. type: Syntax.CatchClause,
  2192. param: param,
  2193. body: parseBlock()
  2194. };
  2195. }
  2196. function parseTryStatement() {
  2197. var block, handlers = [], finalizer = null;
  2198. expectKeyword('try');
  2199. block = parseBlock();
  2200. if (matchKeyword('catch')) {
  2201. handlers.push(parseCatchClause());
  2202. }
  2203. if (matchKeyword('finally')) {
  2204. lex();
  2205. finalizer = parseBlock();
  2206. }
  2207. if (handlers.length === 0 && !finalizer) {
  2208. throwError({}, Messages.NoCatchOrFinally);
  2209. }
  2210. return {
  2211. type: Syntax.TryStatement,
  2212. block: block,
  2213. guardedHandlers: [],
  2214. handlers: handlers,
  2215. finalizer: finalizer
  2216. };
  2217. }
  2218. // 12.15 The debugger statement
  2219. function parseDebuggerStatement() {
  2220. expectKeyword('debugger');
  2221. consumeSemicolon();
  2222. return {
  2223. type: Syntax.DebuggerStatement
  2224. };
  2225. }
  2226. // 12 Statements
  2227. function parseStatement() {
  2228. var token = lookahead(),
  2229. expr,
  2230. labeledBody;
  2231. if (token.type === Token.EOF) {
  2232. throwUnexpected(token);
  2233. }
  2234. if (token.type === Token.Punctuator) {
  2235. switch (token.value) {
  2236. case ';':
  2237. return parseEmptyStatement();
  2238. case '{':
  2239. return parseBlock();
  2240. case '(':
  2241. return parseExpressionStatement();
  2242. default:
  2243. break;
  2244. }
  2245. }
  2246. if (token.type === Token.Keyword) {
  2247. switch (token.value) {
  2248. case 'break':
  2249. return parseBreakStatement();
  2250. case 'continue':
  2251. return parseContinueStatement();
  2252. case 'debugger':
  2253. return parseDebuggerStatement();
  2254. case 'do':
  2255. return parseDoWhileStatement();
  2256. case 'for':
  2257. return parseForStatement();
  2258. case 'function':
  2259. return parseFunctionDeclaration();
  2260. case 'if':
  2261. return parseIfStatement();
  2262. case 'return':
  2263. return parseReturnStatement();
  2264. case 'switch':
  2265. return parseSwitchStatement();
  2266. case 'throw':
  2267. return parseThrowStatement();
  2268. case 'try':
  2269. return parseTryStatement();
  2270. case 'var':
  2271. return parseVariableStatement();
  2272. case 'while':
  2273. return parseWhileStatement();
  2274. case 'with':
  2275. return parseWithStatement();
  2276. default:
  2277. break;
  2278. }
  2279. }
  2280. expr = parseExpression();
  2281. // 12.12 Labelled Statements
  2282. if ((expr.type === Syntax.Identifier) && match(':')) {
  2283. lex();
  2284. if (Object.prototype.hasOwnProperty.call(state.labelSet, expr.name)) {
  2285. throwError({}, Messages.Redeclaration, 'Label', expr.name);
  2286. }
  2287. state.labelSet[expr.name] = true;
  2288. labeledBody = parseStatement();
  2289. delete state.labelSet[expr.name];
  2290. return {
  2291. type: Syntax.LabeledStatement,
  2292. label: expr,
  2293. body: labeledBody
  2294. };
  2295. }
  2296. consumeSemicolon();
  2297. return {
  2298. type: Syntax.ExpressionStatement,
  2299. expression: expr
  2300. };
  2301. }
  2302. // 13 Function Definition
  2303. function parseFunctionSourceElements() {
  2304. var sourceElement, sourceElements = [], token, directive, firstRestricted,
  2305. oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody;
  2306. expect('{');
  2307. while (index < length) {
  2308. token = lookahead();
  2309. if (token.type !== Token.StringLiteral) {
  2310. break;
  2311. }
  2312. sourceElement = parseSourceElement();
  2313. sourceElements.push(sourceElement);
  2314. if (sourceElement.expression.type !== Syntax.Literal) {
  2315. // this is not directive
  2316. break;
  2317. }
  2318. directive = sliceSource(token.range[0] + 1, token.range[1] - 1);
  2319. if (directive === 'use strict') {
  2320. strict = true;
  2321. if (firstRestricted) {
  2322. throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
  2323. }
  2324. } else {
  2325. if (!firstRestricted && token.octal) {
  2326. firstRestricted = token;
  2327. }
  2328. }
  2329. }
  2330. oldLabelSet = state.labelSet;
  2331. oldInIteration = state.inIteration;
  2332. oldInSwitch = state.inSwitch;
  2333. oldInFunctionBody = state.inFunctionBody;
  2334. state.labelSet = {};
  2335. state.inIteration = false;
  2336. state.inSwitch = false;
  2337. state.inFunctionBody = true;
  2338. while (index < length) {
  2339. if (match('}')) {
  2340. break;
  2341. }
  2342. sourceElement = parseSourceElement();
  2343. if (typeof sourceElement === 'undefined') {
  2344. break;
  2345. }
  2346. sourceElements.push(sourceElement);
  2347. }
  2348. expect('}');
  2349. state.labelSet = oldLabelSet;
  2350. state.inIteration = oldInIteration;
  2351. state.inSwitch = oldInSwitch;
  2352. state.inFunctionBody = oldInFunctionBody;
  2353. return {
  2354. type: Syntax.BlockStatement,
  2355. body: sourceElements
  2356. };
  2357. }
  2358. function parseFunctionDeclaration() {
  2359. var id, param, params = [], body, token, stricted, firstRestricted, message, previousStrict, paramSet;
  2360. expectKeyword('function');
  2361. token = lookahead();
  2362. id = parseVariableIdentifier();
  2363. if (strict) {
  2364. if (isRestrictedWord(token.value)) {
  2365. throwErrorTolerant(token, Messages.StrictFunctionName);
  2366. }
  2367. } else {
  2368. if (isRestrictedWord(token.value)) {
  2369. firstRestricted = token;
  2370. message = Messages.StrictFunctionName;
  2371. } else if (isStrictModeReservedWord(token.value)) {
  2372. firstRestricted = token;
  2373. message = Messages.StrictReservedWord;
  2374. }
  2375. }
  2376. expect('(');
  2377. if (!match(')')) {
  2378. paramSet = {};
  2379. while (index < length) {
  2380. token = lookahead();
  2381. param = parseVariableIdentifier();
  2382. if (strict) {
  2383. if (isRestrictedWord(token.value)) {
  2384. stricted = token;
  2385. message = Messages.StrictParamName;
  2386. }
  2387. if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
  2388. stricted = token;
  2389. message = Messages.StrictParamDupe;
  2390. }
  2391. } else if (!firstRestricted) {
  2392. if (isRestrictedWord(token.value)) {
  2393. firstRestricted = token;
  2394. message = Messages.StrictParamName;
  2395. } else if (isStrictModeReservedWord(token.value)) {
  2396. firstRestricted = token;
  2397. message = Messages.StrictReservedWord;
  2398. } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
  2399. firstRestricted = token;
  2400. message = Messages.StrictParamDupe;
  2401. }
  2402. }
  2403. params.push(param);
  2404. paramSet[param.name] = true;
  2405. if (match(')')) {
  2406. break;
  2407. }
  2408. expect(',');
  2409. }
  2410. }
  2411. expect(')');
  2412. previousStrict = strict;
  2413. body = parseFunctionSourceElements();
  2414. if (strict && firstRestricted) {
  2415. throwError(firstRestricted, message);
  2416. }
  2417. if (strict && stricted) {
  2418. throwErrorTolerant(stricted, message);
  2419. }
  2420. strict = previousStrict;
  2421. return {
  2422. type: Syntax.FunctionDeclaration,
  2423. id: id,
  2424. params: params,
  2425. defaults: [],
  2426. body: body,
  2427. rest: null,
  2428. generator: false,
  2429. expression: false
  2430. };
  2431. }
  2432. function parseFunctionExpression() {
  2433. var token, id = null, stricted, firstRestricted, message, param, params = [], body, previousStrict, paramSet;
  2434. expectKeyword('function');
  2435. if (!match('(')) {
  2436. token = lookahead();
  2437. id = parseVariableIdentifier();
  2438. if (strict) {
  2439. if (isRestrictedWord(token.value)) {
  2440. throwErrorTolerant(token, Messages.StrictFunctionName);
  2441. }
  2442. } else {
  2443. if (isRestrictedWord(token.value)) {
  2444. firstRestricted = token;
  2445. message = Messages.StrictFunctionName;
  2446. } else if (isStrictModeReservedWord(token.value)) {
  2447. firstRestricted = token;
  2448. message = Messages.StrictReservedWord;
  2449. }
  2450. }
  2451. }
  2452. expect('(');
  2453. if (!match(')')) {
  2454. paramSet = {};
  2455. while (index < length) {
  2456. token = lookahead();
  2457. param = parseVariableIdentifier();
  2458. if (strict) {
  2459. if (isRestrictedWord(token.value)) {
  2460. stricted = token;
  2461. message = Messages.StrictParamName;
  2462. }
  2463. if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
  2464. stricted = token;
  2465. message = Messages.StrictParamDupe;
  2466. }
  2467. } else if (!firstRestricted) {
  2468. if (isRestrictedWord(token.value)) {
  2469. firstRestricted = token;
  2470. message = Messages.StrictParamName;
  2471. } else if (isStrictModeReservedWord(token.value)) {
  2472. firstRestricted = token;
  2473. message = Messages.StrictReservedWord;
  2474. } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
  2475. firstRestricted = token;
  2476. message = Messages.StrictParamDupe;
  2477. }
  2478. }
  2479. params.push(param);
  2480. paramSet[param.name] = true;
  2481. if (match(')')) {
  2482. break;
  2483. }
  2484. expect(',');
  2485. }
  2486. }
  2487. expect(')');
  2488. previousStrict = strict;
  2489. body = parseFunctionSourceElements();
  2490. if (strict && firstRestricted) {
  2491. throwError(firstRestricted, message);
  2492. }
  2493. if (strict && stricted) {
  2494. throwErrorTolerant(stricted, message);
  2495. }
  2496. strict = previousStrict;
  2497. return {
  2498. type: Syntax.FunctionExpression,
  2499. id: id,
  2500. params: params,
  2501. defaults: [],
  2502. body: body,
  2503. rest: null,
  2504. generator: false,
  2505. expression: false
  2506. };
  2507. }
  2508. // 14 Program
  2509. function parseSourceElement() {
  2510. var token = lookahead();
  2511. if (token.type === Token.Keyword) {
  2512. switch (token.value) {
  2513. case 'const':
  2514. case 'let':
  2515. return parseConstLetDeclaration(token.value);
  2516. case 'function':
  2517. return parseFunctionDeclaration();
  2518. default:
  2519. return parseStatement();
  2520. }
  2521. }
  2522. if (token.type !== Token.EOF) {
  2523. return parseStatement();
  2524. }
  2525. }
  2526. function parseSourceElements() {
  2527. var sourceElement, sourceElements = [], token, directive, firstRestricted;
  2528. while (index < length) {
  2529. token = lookahead();
  2530. if (token.type !== Token.StringLiteral) {
  2531. break;
  2532. }
  2533. sourceElement = parseSourceElement();
  2534. sourceElements.push(sourceElement);
  2535. if (sourceElement.expression.type !== Syntax.Literal) {
  2536. // this is not directive
  2537. break;
  2538. }
  2539. directive = sliceSource(token.range[0] + 1, token.range[1] - 1);
  2540. if (directive === 'use strict') {
  2541. strict = true;
  2542. if (firstRestricted) {
  2543. throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
  2544. }
  2545. } else {
  2546. if (!firstRestricted && token.octal) {
  2547. firstRestricted = token;
  2548. }
  2549. }
  2550. }
  2551. while (index < length) {
  2552. sourceElement = parseSourceElement();
  2553. if (typeof sourceElement === 'undefined') {
  2554. break;
  2555. }
  2556. sourceElements.push(sourceElement);
  2557. }
  2558. return sourceElements;
  2559. }
  2560. function parseProgram() {
  2561. var program;
  2562. strict = false;
  2563. program = {
  2564. type: Syntax.Program,
  2565. body: parseSourceElements()
  2566. };
  2567. return program;
  2568. }
  2569. // The following functions are needed only when the option to preserve
  2570. // the comments is active.
  2571. function addComment(type, value, start, end, loc) {
  2572. assert(typeof start === 'number', 'Comment must have valid position');
  2573. // Because the way the actual token is scanned, often the comments
  2574. // (if any) are skipped twice during the lexical analysis.
  2575. // Thus, we need to skip adding a comment if the comment array already
  2576. // handled it.
  2577. if (extra.comments.length > 0) {
  2578. if (extra.comments[extra.comments.length - 1].range[1] > start) {
  2579. return;
  2580. }
  2581. }
  2582. extra.comments.push({
  2583. type: type,
  2584. value: value,
  2585. range: [start, end],
  2586. loc: loc
  2587. });
  2588. }
  2589. function scanComment() {
  2590. var comment, ch, loc, start, blockComment, lineComment;
  2591. comment = '';
  2592. blockComment = false;
  2593. lineComment = false;
  2594. while (index < length) {
  2595. ch = source[index];
  2596. if (lineComment) {
  2597. ch = source[index++];
  2598. if (isLineTerminator(ch)) {
  2599. loc.end = {
  2600. line: lineNumber,
  2601. column: index - lineStart - 1
  2602. };
  2603. lineComment = false;
  2604. addComment('Line', comment, start, index - 1, loc);
  2605. if (ch === '\r' && source[index] === '\n') {
  2606. ++index;
  2607. }
  2608. ++lineNumber;
  2609. lineStart = index;
  2610. comment = '';
  2611. } else if (index >= length) {
  2612. lineComment = false;
  2613. comment += ch;
  2614. loc.end = {
  2615. line: lineNumber,
  2616. column: length - lineStart
  2617. };
  2618. addComment('Line', comment, start, length, loc);
  2619. } else {
  2620. comment += ch;
  2621. }
  2622. } else if (blockComment) {
  2623. if (isLineTerminator(ch)) {
  2624. if (ch === '\r' && source[index + 1] === '\n') {
  2625. ++index;
  2626. comment += '\r\n';
  2627. } else {
  2628. comment += ch;
  2629. }
  2630. ++lineNumber;
  2631. ++index;
  2632. lineStart = index;
  2633. if (index >= length) {
  2634. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  2635. }
  2636. } else {
  2637. ch = source[index++];
  2638. if (index >= length) {
  2639. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  2640. }
  2641. comment += ch;
  2642. if (ch === '*') {
  2643. ch = source[index];
  2644. if (ch === '/') {
  2645. comment = comment.substr(0, comment.length - 1);
  2646. blockComment = false;
  2647. ++index;
  2648. loc.end = {
  2649. line: lineNumber,
  2650. column: index - lineStart
  2651. };
  2652. addComment('Block', comment, start, index, loc);
  2653. comment = '';
  2654. }
  2655. }
  2656. }
  2657. } else if (ch === '/') {
  2658. ch = source[index + 1];
  2659. if (ch === '/') {
  2660. loc = {
  2661. start: {
  2662. line: lineNumber,
  2663. column: index - lineStart
  2664. }
  2665. };
  2666. start = index;
  2667. index += 2;
  2668. lineComment = true;
  2669. if (index >= length) {
  2670. loc.end = {
  2671. line: lineNumber,
  2672. column: index - lineStart
  2673. };
  2674. lineComment = false;
  2675. addComment('Line', comment, start, index, loc);
  2676. }
  2677. } else if (ch === '*') {
  2678. start = index;
  2679. index += 2;
  2680. blockComment = true;
  2681. loc = {
  2682. start: {
  2683. line: lineNumber,
  2684. column: index - lineStart - 2
  2685. }
  2686. };
  2687. if (index >= length) {
  2688. throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
  2689. }
  2690. } else {
  2691. break;
  2692. }
  2693. } else if (isWhiteSpace(ch)) {
  2694. ++index;
  2695. } else if (isLineTerminator(ch)) {
  2696. ++index;
  2697. if (ch === '\r' && source[index] === '\n') {
  2698. ++index;
  2699. }
  2700. ++lineNumber;
  2701. lineStart = index;
  2702. } else {
  2703. break;
  2704. }
  2705. }
  2706. }
  2707. function filterCommentLocation() {
  2708. var i, entry, comment, comments = [];
  2709. for (i = 0; i < extra.comments.length; ++i) {
  2710. entry = extra.comments[i];
  2711. comment = {
  2712. type: entry.type,
  2713. value: entry.value
  2714. };
  2715. if (extra.range) {
  2716. comment.range = entry.range;
  2717. }
  2718. if (extra.loc) {
  2719. comment.loc = entry.loc;
  2720. }
  2721. comments.push(comment);
  2722. }
  2723. extra.comments = comments;
  2724. }
  2725. function collectToken() {
  2726. var start, loc, token, range, value;
  2727. skipComment();
  2728. start = index;
  2729. loc = {
  2730. start: {
  2731. line: lineNumber,
  2732. column: index - lineStart
  2733. }
  2734. };
  2735. token = extra.advance();
  2736. loc.end = {
  2737. line: lineNumber,
  2738. column: index - lineStart
  2739. };
  2740. if (token.type !== Token.EOF) {
  2741. range = [token.range[0], token.range[1]];
  2742. value = sliceSource(token.range[0], token.range[1]);
  2743. extra.tokens.push({
  2744. type: TokenName[token.type],
  2745. value: value,
  2746. range: range,
  2747. loc: loc
  2748. });
  2749. }
  2750. return token;
  2751. }
  2752. function collectRegex() {
  2753. var pos, loc, regex, token;
  2754. skipComment();
  2755. pos = index;
  2756. loc = {
  2757. start: {
  2758. line: lineNumber,
  2759. column: index - lineStart
  2760. }
  2761. };
  2762. regex = extra.scanRegExp();
  2763. loc.end = {
  2764. line: lineNumber,
  2765. column: index - lineStart
  2766. };
  2767. // Pop the previous token, which is likely '/' or '/='
  2768. if (extra.tokens.length > 0) {
  2769. token = extra.tokens[extra.tokens.length - 1];
  2770. if (token.range[0] === pos && token.type === 'Punctuator') {
  2771. if (token.value === '/' || token.value === '/=') {
  2772. extra.tokens.pop();
  2773. }
  2774. }
  2775. }
  2776. extra.tokens.push({
  2777. type: 'RegularExpression',
  2778. value: regex.literal,
  2779. range: [pos, index],
  2780. loc: loc
  2781. });
  2782. return regex;
  2783. }
  2784. function filterTokenLocation() {
  2785. var i, entry, token, tokens = [];
  2786. for (i = 0; i < extra.tokens.length; ++i) {
  2787. entry = extra.tokens[i];
  2788. token = {
  2789. type: entry.type,
  2790. value: entry.value
  2791. };
  2792. if (extra.range) {
  2793. token.range = entry.range;
  2794. }
  2795. if (extra.loc) {
  2796. token.loc = entry.loc;
  2797. }
  2798. tokens.push(token);
  2799. }
  2800. extra.tokens = tokens;
  2801. }
  2802. function createLiteral(token) {
  2803. return {
  2804. type: Syntax.Literal,
  2805. value: token.value
  2806. };
  2807. }
  2808. function createRawLiteral(token) {
  2809. return {
  2810. type: Syntax.Literal,
  2811. value: token.value,
  2812. raw: sliceSource(token.range[0], token.range[1])
  2813. };
  2814. }
  2815. function createLocationMarker() {
  2816. var marker = {};
  2817. marker.range = [index, index];
  2818. marker.loc = {
  2819. start: {
  2820. line: lineNumber,
  2821. column: index - lineStart
  2822. },
  2823. end: {
  2824. line: lineNumber,
  2825. column: index - lineStart
  2826. }
  2827. };
  2828. marker.end = function () {
  2829. this.range[1] = index;
  2830. this.loc.end.line = lineNumber;
  2831. this.loc.end.column = index - lineStart;
  2832. };
  2833. marker.applyGroup = function (node) {
  2834. if (extra.range) {
  2835. node.groupRange = [this.range[0], this.range[1]];
  2836. }
  2837. if (extra.loc) {
  2838. node.groupLoc = {
  2839. start: {
  2840. line: this.loc.start.line,
  2841. column: this.loc.start.column
  2842. },
  2843. end: {
  2844. line: this.loc.end.line,
  2845. column: this.loc.end.column
  2846. }
  2847. };
  2848. }
  2849. };
  2850. marker.apply = function (node) {
  2851. if (extra.range) {
  2852. node.range = [this.range[0], this.range[1]];
  2853. }
  2854. if (extra.loc) {
  2855. node.loc = {
  2856. start: {
  2857. line: this.loc.start.line,
  2858. column: this.loc.start.column
  2859. },
  2860. end: {
  2861. line: this.loc.end.line,
  2862. column: this.loc.end.column
  2863. }
  2864. };
  2865. }
  2866. };
  2867. return marker;
  2868. }
  2869. function trackGroupExpression() {
  2870. var marker, expr;
  2871. skipComment();
  2872. marker = createLocationMarker();
  2873. expect('(');
  2874. expr = parseExpression();
  2875. expect(')');
  2876. marker.end();
  2877. marker.applyGroup(expr);
  2878. return expr;
  2879. }
  2880. function trackLeftHandSideExpression() {
  2881. var marker, expr;
  2882. skipComment();
  2883. marker = createLocationMarker();
  2884. expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
  2885. while (match('.') || match('[')) {
  2886. if (match('[')) {
  2887. expr = {
  2888. type: Syntax.MemberExpression,
  2889. computed: true,
  2890. object: expr,
  2891. property: parseComputedMember()
  2892. };
  2893. marker.end();
  2894. marker.apply(expr);
  2895. } else {
  2896. expr = {
  2897. type: Syntax.MemberExpression,
  2898. computed: false,
  2899. object: expr,
  2900. property: parseNonComputedMember()
  2901. };
  2902. marker.end();
  2903. marker.apply(expr);
  2904. }
  2905. }
  2906. return expr;
  2907. }
  2908. function trackLeftHandSideExpressionAllowCall() {
  2909. var marker, expr;
  2910. skipComment();
  2911. marker = createLocationMarker();
  2912. expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
  2913. while (match('.') || match('[') || match('(')) {
  2914. if (match('(')) {
  2915. expr = {
  2916. type: Syntax.CallExpression,
  2917. callee: expr,
  2918. 'arguments': parseArguments()
  2919. };
  2920. marker.end();
  2921. marker.apply(expr);
  2922. } else if (match('[')) {
  2923. expr = {
  2924. type: Syntax.MemberExpression,
  2925. computed: true,
  2926. object: expr,
  2927. property: parseComputedMember()
  2928. };
  2929. marker.end();
  2930. marker.apply(expr);
  2931. } else {
  2932. expr = {
  2933. type: Syntax.MemberExpression,
  2934. computed: false,
  2935. object: expr,
  2936. property: parseNonComputedMember()
  2937. };
  2938. marker.end();
  2939. marker.apply(expr);
  2940. }
  2941. }
  2942. return expr;
  2943. }
  2944. function filterGroup(node) {
  2945. var n, i, entry;
  2946. n = (Object.prototype.toString.apply(node) === '[object Array]') ? [] : {};
  2947. for (i in node) {
  2948. if (node.hasOwnProperty(i) && i !== 'groupRange' && i !== 'groupLoc') {
  2949. entry = node[i];
  2950. if (entry === null || typeof entry !== 'object' || entry instanceof RegExp) {
  2951. n[i] = entry;
  2952. } else {
  2953. n[i] = filterGroup(entry);
  2954. }
  2955. }
  2956. }
  2957. return n;
  2958. }
  2959. function wrapTrackingFunction(range, loc) {
  2960. return function (parseFunction) {
  2961. function isBinary(node) {
  2962. return node.type === Syntax.LogicalExpression ||
  2963. node.type === Syntax.BinaryExpression;
  2964. }
  2965. function visit(node) {
  2966. var start, end;
  2967. if (isBinary(node.left)) {
  2968. visit(node.left);
  2969. }
  2970. if (isBinary(node.right)) {
  2971. visit(node.right);
  2972. }
  2973. if (range) {
  2974. if (node.left.groupRange || node.right.groupRange) {
  2975. start = node.left.groupRange ? node.left.groupRange[0] : node.left.range[0];
  2976. end = node.right.groupRange ? node.right.groupRange[1] : node.right.range[1];
  2977. node.range = [start, end];
  2978. } else if (typeof node.range === 'undefined') {
  2979. start = node.left.range[0];
  2980. end = node.right.range[1];
  2981. node.range = [start, end];
  2982. }
  2983. }
  2984. if (loc) {
  2985. if (node.left.groupLoc || node.right.groupLoc) {
  2986. start = node.left.groupLoc ? node.left.groupLoc.start : node.left.loc.start;
  2987. end = node.right.groupLoc ? node.right.groupLoc.end : node.right.loc.end;
  2988. node.loc = {
  2989. start: start,
  2990. end: end
  2991. };
  2992. } else if (typeof node.loc === 'undefined') {
  2993. node.loc = {
  2994. start: node.left.loc.start,
  2995. end: node.right.loc.end
  2996. };
  2997. }
  2998. }
  2999. }
  3000. return function () {
  3001. var marker, node;
  3002. skipComment();
  3003. marker = createLocationMarker();
  3004. node = parseFunction.apply(null, arguments);
  3005. marker.end();
  3006. if (range && typeof node.range === 'undefined') {
  3007. marker.apply(node);
  3008. }
  3009. if (loc && typeof node.loc === 'undefined') {
  3010. marker.apply(node);
  3011. }
  3012. if (isBinary(node)) {
  3013. visit(node);
  3014. }
  3015. return node;
  3016. };
  3017. };
  3018. }
  3019. function patch() {
  3020. var wrapTracking;
  3021. if (extra.comments) {
  3022. extra.skipComment = skipComment;
  3023. skipComment = scanComment;
  3024. }
  3025. if (extra.raw) {
  3026. extra.createLiteral = createLiteral;
  3027. createLiteral = createRawLiteral;
  3028. }
  3029. if (extra.range || extra.loc) {
  3030. extra.parseGroupExpression = parseGroupExpression;
  3031. extra.parseLeftHandSideExpression = parseLeftHandSideExpression;
  3032. extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall;
  3033. parseGroupExpression = trackGroupExpression;
  3034. parseLeftHandSideExpression = trackLeftHandSideExpression;
  3035. parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall;
  3036. wrapTracking = wrapTrackingFunction(extra.range, extra.loc);
  3037. extra.parseAdditiveExpression = parseAdditiveExpression;
  3038. extra.parseAssignmentExpression = parseAssignmentExpression;
  3039. extra.parseBitwiseANDExpression = parseBitwiseANDExpression;
  3040. extra.parseBitwiseORExpression = parseBitwiseORExpression;
  3041. extra.parseBitwiseXORExpression = parseBitwiseXORExpression;
  3042. extra.parseBlock = parseBlock;
  3043. extra.parseFunctionSourceElements = parseFunctionSourceElements;
  3044. extra.parseCatchClause = parseCatchClause;
  3045. extra.parseComputedMember = parseComputedMember;
  3046. extra.parseConditionalExpression = parseConditionalExpression;
  3047. extra.parseConstLetDeclaration = parseConstLetDeclaration;
  3048. extra.parseEqualityExpression = parseEqualityExpression;
  3049. extra.parseExpression = parseExpression;
  3050. extra.parseForVariableDeclaration = parseForVariableDeclaration;
  3051. extra.parseFunctionDeclaration = parseFunctionDeclaration;
  3052. extra.parseFunctionExpression = parseFunctionExpression;
  3053. extra.parseLogicalANDExpression = parseLogicalANDExpression;
  3054. extra.parseLogicalORExpression = parseLogicalORExpression;
  3055. extra.parseMultiplicativeExpression = parseMultiplicativeExpression;
  3056. extra.parseNewExpression = parseNewExpression;
  3057. extra.parseNonComputedProperty = parseNonComputedProperty;
  3058. extra.parseObjectProperty = parseObjectProperty;
  3059. extra.parseObjectPropertyKey = parseObjectPropertyKey;
  3060. extra.parsePostfixExpression = parsePostfixExpression;
  3061. extra.parsePrimaryExpression = parsePrimaryExpression;
  3062. extra.parseProgram = parseProgram;
  3063. extra.parsePropertyFunction = parsePropertyFunction;
  3064. extra.parseRelationalExpression = parseRelationalExpression;
  3065. extra.parseStatement = parseStatement;
  3066. extra.parseShiftExpression = parseShiftExpression;
  3067. extra.parseSwitchCase = parseSwitchCase;
  3068. extra.parseUnaryExpression = parseUnaryExpression;
  3069. extra.parseVariableDeclaration = parseVariableDeclaration;
  3070. extra.parseVariableIdentifier = parseVariableIdentifier;
  3071. parseAdditiveExpression = wrapTracking(extra.parseAdditiveExpression);
  3072. parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression);
  3073. parseBitwiseANDExpression = wrapTracking(extra.parseBitwiseANDExpression);
  3074. parseBitwiseORExpression = wrapTracking(extra.parseBitwiseORExpression);
  3075. parseBitwiseXORExpression = wrapTracking(extra.parseBitwiseXORExpression);
  3076. parseBlock = wrapTracking(extra.parseBlock);
  3077. parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements);
  3078. parseCatchClause = wrapTracking(extra.parseCatchClause);
  3079. parseComputedMember = wrapTracking(extra.parseComputedMember);
  3080. parseConditionalExpression = wrapTracking(extra.parseConditionalExpression);
  3081. parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration);
  3082. parseEqualityExpression = wrapTracking(extra.parseEqualityExpression);
  3083. parseExpression = wrapTracking(extra.parseExpression);
  3084. parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration);
  3085. parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration);
  3086. parseFunctionExpression = wrapTracking(extra.parseFunctionExpression);
  3087. parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression);
  3088. parseLogicalANDExpression = wrapTracking(extra.parseLogicalANDExpression);
  3089. parseLogicalORExpression = wrapTracking(extra.parseLogicalORExpression);
  3090. parseMultiplicativeExpression = wrapTracking(extra.parseMultiplicativeExpression);
  3091. parseNewExpression = wrapTracking(extra.parseNewExpression);
  3092. parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty);
  3093. parseObjectProperty = wrapTracking(extra.parseObjectProperty);
  3094. parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey);
  3095. parsePostfixExpression = wrapTracking(extra.parsePostfixExpression);
  3096. parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression);
  3097. parseProgram = wrapTracking(extra.parseProgram);
  3098. parsePropertyFunction = wrapTracking(extra.parsePropertyFunction);
  3099. parseRelationalExpression = wrapTracking(extra.parseRelationalExpression);
  3100. parseStatement = wrapTracking(extra.parseStatement);
  3101. parseShiftExpression = wrapTracking(extra.parseShiftExpression);
  3102. parseSwitchCase = wrapTracking(extra.parseSwitchCase);
  3103. parseUnaryExpression = wrapTracking(extra.parseUnaryExpression);
  3104. parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration);
  3105. parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier);
  3106. }
  3107. if (typeof extra.tokens !== 'undefined') {
  3108. extra.advance = advance;
  3109. extra.scanRegExp = scanRegExp;
  3110. advance = collectToken;
  3111. scanRegExp = collectRegex;
  3112. }
  3113. }
  3114. function unpatch() {
  3115. if (typeof extra.skipComment === 'function') {
  3116. skipComment = extra.skipComment;
  3117. }
  3118. if (extra.raw) {
  3119. createLiteral = extra.createLiteral;
  3120. }
  3121. if (extra.range || extra.loc) {
  3122. parseAdditiveExpression = extra.parseAdditiveExpression;
  3123. parseAssignmentExpression = extra.parseAssignmentExpression;
  3124. parseBitwiseANDExpression = extra.parseBitwiseANDExpression;
  3125. parseBitwiseORExpression = extra.parseBitwiseORExpression;
  3126. parseBitwiseXORExpression = extra.parseBitwiseXORExpression;
  3127. parseBlock = extra.parseBlock;
  3128. parseFunctionSourceElements = extra.parseFunctionSourceElements;
  3129. parseCatchClause = extra.parseCatchClause;
  3130. parseComputedMember = extra.parseComputedMember;
  3131. parseConditionalExpression = extra.parseConditionalExpression;
  3132. parseConstLetDeclaration = extra.parseConstLetDeclaration;
  3133. parseEqualityExpression = extra.parseEqualityExpression;
  3134. parseExpression = extra.parseExpression;
  3135. parseForVariableDeclaration = extra.parseForVariableDeclaration;
  3136. parseFunctionDeclaration = extra.parseFunctionDeclaration;
  3137. parseFunctionExpression = extra.parseFunctionExpression;
  3138. parseGroupExpression = extra.parseGroupExpression;
  3139. parseLeftHandSideExpression = extra.parseLeftHandSideExpression;
  3140. parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall;
  3141. parseLogicalANDExpression = extra.parseLogicalANDExpression;
  3142. parseLogicalORExpression = extra.parseLogicalORExpression;
  3143. parseMultiplicativeExpression = extra.parseMultiplicativeExpression;
  3144. parseNewExpression = extra.parseNewExpression;
  3145. parseNonComputedProperty = extra.parseNonComputedProperty;
  3146. parseObjectProperty = extra.parseObjectProperty;
  3147. parseObjectPropertyKey = extra.parseObjectPropertyKey;
  3148. parsePrimaryExpression = extra.parsePrimaryExpression;
  3149. parsePostfixExpression = extra.parsePostfixExpression;
  3150. parseProgram = extra.parseProgram;
  3151. parsePropertyFunction = extra.parsePropertyFunction;
  3152. parseRelationalExpression = extra.parseRelationalExpression;
  3153. parseStatement = extra.parseStatement;
  3154. parseShiftExpression = extra.parseShiftExpression;
  3155. parseSwitchCase = extra.parseSwitchCase;
  3156. parseUnaryExpression = extra.parseUnaryExpression;
  3157. parseVariableDeclaration = extra.parseVariableDeclaration;
  3158. parseVariableIdentifier = extra.parseVariableIdentifier;
  3159. }
  3160. if (typeof extra.scanRegExp === 'function') {
  3161. advance = extra.advance;
  3162. scanRegExp = extra.scanRegExp;
  3163. }
  3164. }
  3165. function stringToArray(str) {
  3166. var length = str.length,
  3167. result = [],
  3168. i;
  3169. for (i = 0; i < length; ++i) {
  3170. result[i] = str.charAt(i);
  3171. }
  3172. return result;
  3173. }
  3174. function parse(code, options) {
  3175. var program, toString;
  3176. toString = String;
  3177. if (typeof code !== 'string' && !(code instanceof String)) {
  3178. code = toString(code);
  3179. }
  3180. source = code;
  3181. index = 0;
  3182. lineNumber = (source.length > 0) ? 1 : 0;
  3183. lineStart = 0;
  3184. length = source.length;
  3185. buffer = null;
  3186. state = {
  3187. allowIn: true,
  3188. labelSet: {},
  3189. inFunctionBody: false,
  3190. inIteration: false,
  3191. inSwitch: false
  3192. };
  3193. extra = {};
  3194. if (typeof options !== 'undefined') {
  3195. extra.range = (typeof options.range === 'boolean') && options.range;
  3196. extra.loc = (typeof options.loc === 'boolean') && options.loc;
  3197. extra.raw = (typeof options.raw === 'boolean') && options.raw;
  3198. if (typeof options.tokens === 'boolean' && options.tokens) {
  3199. extra.tokens = [];
  3200. }
  3201. if (typeof options.comment === 'boolean' && options.comment) {
  3202. extra.comments = [];
  3203. }
  3204. if (typeof options.tolerant === 'boolean' && options.tolerant) {
  3205. extra.errors = [];
  3206. }
  3207. }
  3208. if (length > 0) {
  3209. if (typeof source[0] === 'undefined') {
  3210. // Try first to convert to a string. This is good as fast path
  3211. // for old IE which understands string indexing for string
  3212. // literals only and not for string object.
  3213. if (code instanceof String) {
  3214. source = code.valueOf();
  3215. }
  3216. // Force accessing the characters via an array.
  3217. if (typeof source[0] === 'undefined') {
  3218. source = stringToArray(code);
  3219. }
  3220. }
  3221. }
  3222. patch();
  3223. try {
  3224. program = parseProgram();
  3225. if (typeof extra.comments !== 'undefined') {
  3226. filterCommentLocation();
  3227. program.comments = extra.comments;
  3228. }
  3229. if (typeof extra.tokens !== 'undefined') {
  3230. filterTokenLocation();
  3231. program.tokens = extra.tokens;
  3232. }
  3233. if (typeof extra.errors !== 'undefined') {
  3234. program.errors = extra.errors;
  3235. }
  3236. if (extra.range || extra.loc) {
  3237. program.body = filterGroup(program.body);
  3238. }
  3239. } catch (e) {
  3240. throw e;
  3241. } finally {
  3242. unpatch();
  3243. extra = {};
  3244. }
  3245. return program;
  3246. }
  3247. // Sync with package.json.
  3248. exports.version = '1.0.4';
  3249. exports.parse = parse;
  3250. // Deep copy.
  3251. exports.Syntax = (function () {
  3252. var name, types = {};
  3253. if (typeof Object.create === 'function') {
  3254. types = Object.create(null);
  3255. }
  3256. for (name in Syntax) {
  3257. if (Syntax.hasOwnProperty(name)) {
  3258. types[name] = Syntax[name];
  3259. }
  3260. }
  3261. if (typeof Object.freeze === 'function') {
  3262. Object.freeze(types);
  3263. }
  3264. return types;
  3265. }());
  3266. }));
  3267. /* vim: set sw=4 ts=4 et tw=80 : */