notevil.js 147 KB

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