acorn.es.js 122 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401
  1. // Reserved word lists for various dialects of the language
  2. var reservedWords = {
  3. 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
  4. 5: "class enum extends super const export import",
  5. 6: "enum",
  6. strict: "implements interface let package private protected public static yield",
  7. strictBind: "eval arguments"
  8. }
  9. // And the keywords
  10. var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"
  11. var keywords = {
  12. 5: ecma5AndLessKeywords,
  13. 6: ecma5AndLessKeywords + " const class extends export import super"
  14. }
  15. // ## Character categories
  16. // Big ugly regular expressions that match characters in the
  17. // whitespace, identifier, and identifier-start categories. These
  18. // are only applied when a character is found to actually have a
  19. // code point above 128.
  20. // Generated by `bin/generate-identifier-regex.js`.
  21. var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\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-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\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\u0af9\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-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\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-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\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\u2118-\u211d\u2124\u2126\u2128\u212a-\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\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\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"
  22. var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"
  23. var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]")
  24. var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]")
  25. nonASCIIidentifierStartChars = nonASCIIidentifierChars = null
  26. // These are a run-length and offset encoded representation of the
  27. // >0xffff code points that are a valid part of identifiers. The
  28. // offset starts at 0x10000, and each pair of numbers represents an
  29. // offset to the next range, and then a size of the range. They were
  30. // generated by bin/generate-identifier-regex.js
  31. var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541]
  32. var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239]
  33. // This has a complexity linear to the value of the code. The
  34. // assumption is that looking up astral identifier characters is
  35. // rare.
  36. function isInAstralSet(code, set) {
  37. var pos = 0x10000
  38. for (var i = 0; i < set.length; i += 2) {
  39. pos += set[i]
  40. if (pos > code) return false
  41. pos += set[i + 1]
  42. if (pos >= code) return true
  43. }
  44. }
  45. // Test whether a given character code starts an identifier.
  46. function isIdentifierStart(code, astral) {
  47. if (code < 65) return code === 36
  48. if (code < 91) return true
  49. if (code < 97) return code === 95
  50. if (code < 123) return true
  51. if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code))
  52. if (astral === false) return false
  53. return isInAstralSet(code, astralIdentifierStartCodes)
  54. }
  55. // Test whether a given character is part of an identifier.
  56. function isIdentifierChar(code, astral) {
  57. if (code < 48) return code === 36
  58. if (code < 58) return true
  59. if (code < 65) return false
  60. if (code < 91) return true
  61. if (code < 97) return code === 95
  62. if (code < 123) return true
  63. if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code))
  64. if (astral === false) return false
  65. return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
  66. }
  67. // ## Token types
  68. // The assignment of fine-grained, information-carrying type objects
  69. // allows the tokenizer to store the information it has about a
  70. // token in a way that is very cheap for the parser to look up.
  71. // All token type variables start with an underscore, to make them
  72. // easy to recognize.
  73. // The `beforeExpr` property is used to disambiguate between regular
  74. // expressions and divisions. It is set on all token types that can
  75. // be followed by an expression (thus, a slash after them would be a
  76. // regular expression).
  77. //
  78. // The `startsExpr` property is used to check if the token ends a
  79. // `yield` expression. It is set on all token types that either can
  80. // directly start an expression (like a quotation mark) or can
  81. // continue an expression (like the body of a string).
  82. //
  83. // `isLoop` marks a keyword as starting a loop, which is important
  84. // to know when parsing a label, in order to allow or disallow
  85. // continue jumps to that label.
  86. var TokenType = function TokenType(label, conf) {
  87. if ( conf === void 0 ) conf = {};
  88. this.label = label
  89. this.keyword = conf.keyword
  90. this.beforeExpr = !!conf.beforeExpr
  91. this.startsExpr = !!conf.startsExpr
  92. this.isLoop = !!conf.isLoop
  93. this.isAssign = !!conf.isAssign
  94. this.prefix = !!conf.prefix
  95. this.postfix = !!conf.postfix
  96. this.binop = conf.binop || null
  97. this.updateContext = null
  98. };
  99. function binop(name, prec) {
  100. return new TokenType(name, {beforeExpr: true, binop: prec})
  101. }
  102. var beforeExpr = {beforeExpr: true};
  103. var startsExpr = {startsExpr: true};
  104. // Map keyword names to token types.
  105. var keywordTypes = {}
  106. // Succinct definitions of keyword token types
  107. function kw(name, options) {
  108. if ( options === void 0 ) options = {};
  109. options.keyword = name
  110. return keywordTypes[name] = new TokenType(name, options)
  111. }
  112. var tt = {
  113. num: new TokenType("num", startsExpr),
  114. regexp: new TokenType("regexp", startsExpr),
  115. string: new TokenType("string", startsExpr),
  116. name: new TokenType("name", startsExpr),
  117. eof: new TokenType("eof"),
  118. // Punctuation token types.
  119. bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
  120. bracketR: new TokenType("]"),
  121. braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
  122. braceR: new TokenType("}"),
  123. parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
  124. parenR: new TokenType(")"),
  125. comma: new TokenType(",", beforeExpr),
  126. semi: new TokenType(";", beforeExpr),
  127. colon: new TokenType(":", beforeExpr),
  128. dot: new TokenType("."),
  129. question: new TokenType("?", beforeExpr),
  130. arrow: new TokenType("=>", beforeExpr),
  131. template: new TokenType("template"),
  132. ellipsis: new TokenType("...", beforeExpr),
  133. backQuote: new TokenType("`", startsExpr),
  134. dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
  135. // Operators. These carry several kinds of properties to help the
  136. // parser use them properly (the presence of these properties is
  137. // what categorizes them as operators).
  138. //
  139. // `binop`, when present, specifies that this operator is a binary
  140. // operator, and will refer to its precedence.
  141. //
  142. // `prefix` and `postfix` mark the operator as a prefix or postfix
  143. // unary operator.
  144. //
  145. // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
  146. // binary operators with a very low precedence, that should result
  147. // in AssignmentExpression nodes.
  148. eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
  149. assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
  150. incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
  151. prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}),
  152. logicalOR: binop("||", 1),
  153. logicalAND: binop("&&", 2),
  154. bitwiseOR: binop("|", 3),
  155. bitwiseXOR: binop("^", 4),
  156. bitwiseAND: binop("&", 5),
  157. equality: binop("==/!=", 6),
  158. relational: binop("</>", 7),
  159. bitShift: binop("<</>>", 8),
  160. plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
  161. modulo: binop("%", 10),
  162. star: binop("*", 10),
  163. slash: binop("/", 10),
  164. starstar: new TokenType("**", {beforeExpr: true}),
  165. // Keyword token types.
  166. _break: kw("break"),
  167. _case: kw("case", beforeExpr),
  168. _catch: kw("catch"),
  169. _continue: kw("continue"),
  170. _debugger: kw("debugger"),
  171. _default: kw("default", beforeExpr),
  172. _do: kw("do", {isLoop: true, beforeExpr: true}),
  173. _else: kw("else", beforeExpr),
  174. _finally: kw("finally"),
  175. _for: kw("for", {isLoop: true}),
  176. _function: kw("function", startsExpr),
  177. _if: kw("if"),
  178. _return: kw("return", beforeExpr),
  179. _switch: kw("switch"),
  180. _throw: kw("throw", beforeExpr),
  181. _try: kw("try"),
  182. _var: kw("var"),
  183. _const: kw("const"),
  184. _while: kw("while", {isLoop: true}),
  185. _with: kw("with"),
  186. _new: kw("new", {beforeExpr: true, startsExpr: true}),
  187. _this: kw("this", startsExpr),
  188. _super: kw("super", startsExpr),
  189. _class: kw("class"),
  190. _extends: kw("extends", beforeExpr),
  191. _export: kw("export"),
  192. _import: kw("import"),
  193. _null: kw("null", startsExpr),
  194. _true: kw("true", startsExpr),
  195. _false: kw("false", startsExpr),
  196. _in: kw("in", {beforeExpr: true, binop: 7}),
  197. _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
  198. _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
  199. _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
  200. _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
  201. }
  202. // Matches a whole line break (where CRLF is considered a single
  203. // line break). Used to count lines.
  204. var lineBreak = /\r\n?|\n|\u2028|\u2029/
  205. var lineBreakG = new RegExp(lineBreak.source, "g")
  206. function isNewLine(code) {
  207. return code === 10 || code === 13 || code === 0x2028 || code === 0x2029
  208. }
  209. var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/
  210. var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g
  211. function isArray(obj) {
  212. return Object.prototype.toString.call(obj) === "[object Array]"
  213. }
  214. // Checks if an object has a property.
  215. function has(obj, propName) {
  216. return Object.prototype.hasOwnProperty.call(obj, propName)
  217. }
  218. // These are used when `options.locations` is on, for the
  219. // `startLoc` and `endLoc` properties.
  220. var Position = function Position(line, col) {
  221. this.line = line
  222. this.column = col
  223. };
  224. Position.prototype.offset = function offset (n) {
  225. return new Position(this.line, this.column + n)
  226. };
  227. var SourceLocation = function SourceLocation(p, start, end) {
  228. this.start = start
  229. this.end = end
  230. if (p.sourceFile !== null) this.source = p.sourceFile
  231. };
  232. // The `getLineInfo` function is mostly useful when the
  233. // `locations` option is off (for performance reasons) and you
  234. // want to find the line/column position for a given character
  235. // offset. `input` should be the code string that the offset refers
  236. // into.
  237. function getLineInfo(input, offset) {
  238. for (var line = 1, cur = 0;;) {
  239. lineBreakG.lastIndex = cur
  240. var match = lineBreakG.exec(input)
  241. if (match && match.index < offset) {
  242. ++line
  243. cur = match.index + match[0].length
  244. } else {
  245. return new Position(line, offset - cur)
  246. }
  247. }
  248. }
  249. // A second optional argument can be given to further configure
  250. // the parser process. These options are recognized:
  251. var defaultOptions = {
  252. // `ecmaVersion` indicates the ECMAScript version to parse. Must
  253. // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support
  254. // for strict mode, the set of reserved words, and support for
  255. // new syntax features. The default is 7.
  256. ecmaVersion: 7,
  257. // `sourceType` indicates the mode the code should be parsed in.
  258. // Can be either `"script"` or `"module"`. This influences global
  259. // strict mode and parsing of `import` and `export` declarations.
  260. sourceType: "script",
  261. // `onInsertedSemicolon` can be a callback that will be called
  262. // when a semicolon is automatically inserted. It will be passed
  263. // th position of the comma as an offset, and if `locations` is
  264. // enabled, it is given the location as a `{line, column}` object
  265. // as second argument.
  266. onInsertedSemicolon: null,
  267. // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
  268. // trailing commas.
  269. onTrailingComma: null,
  270. // By default, reserved words are only enforced if ecmaVersion >= 5.
  271. // Set `allowReserved` to a boolean value to explicitly turn this on
  272. // an off. When this option has the value "never", reserved words
  273. // and keywords can also not be used as property names.
  274. allowReserved: null,
  275. // When enabled, a return at the top level is not considered an
  276. // error.
  277. allowReturnOutsideFunction: false,
  278. // When enabled, import/export statements are not constrained to
  279. // appearing at the top of the program.
  280. allowImportExportEverywhere: false,
  281. // When enabled, hashbang directive in the beginning of file
  282. // is allowed and treated as a line comment.
  283. allowHashBang: false,
  284. // When `locations` is on, `loc` properties holding objects with
  285. // `start` and `end` properties in `{line, column}` form (with
  286. // line being 1-based and column 0-based) will be attached to the
  287. // nodes.
  288. locations: false,
  289. // A function can be passed as `onToken` option, which will
  290. // cause Acorn to call that function with object in the same
  291. // format as tokens returned from `tokenizer().getToken()`. Note
  292. // that you are not allowed to call the parser from the
  293. // callback—that will corrupt its internal state.
  294. onToken: null,
  295. // A function can be passed as `onComment` option, which will
  296. // cause Acorn to call that function with `(block, text, start,
  297. // end)` parameters whenever a comment is skipped. `block` is a
  298. // boolean indicating whether this is a block (`/* */`) comment,
  299. // `text` is the content of the comment, and `start` and `end` are
  300. // character offsets that denote the start and end of the comment.
  301. // When the `locations` option is on, two more parameters are
  302. // passed, the full `{line, column}` locations of the start and
  303. // end of the comments. Note that you are not allowed to call the
  304. // parser from the callback—that will corrupt its internal state.
  305. onComment: null,
  306. // Nodes have their start and end characters offsets recorded in
  307. // `start` and `end` properties (directly on the node, rather than
  308. // the `loc` object, which holds line/column data. To also add a
  309. // [semi-standardized][range] `range` property holding a `[start,
  310. // end]` array with the same numbers, set the `ranges` option to
  311. // `true`.
  312. //
  313. // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
  314. ranges: false,
  315. // It is possible to parse multiple files into a single AST by
  316. // passing the tree produced by parsing the first file as
  317. // `program` option in subsequent parses. This will add the
  318. // toplevel forms of the parsed file to the `Program` (top) node
  319. // of an existing parse tree.
  320. program: null,
  321. // When `locations` is on, you can pass this to record the source
  322. // file in every node's `loc` object.
  323. sourceFile: null,
  324. // This value, if given, is stored in every node, whether
  325. // `locations` is on or off.
  326. directSourceFile: null,
  327. // When enabled, parenthesized expressions are represented by
  328. // (non-standard) ParenthesizedExpression nodes
  329. preserveParens: false,
  330. plugins: {}
  331. }
  332. // Interpret and default an options object
  333. function getOptions(opts) {
  334. var options = {}
  335. for (var opt in defaultOptions)
  336. options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]
  337. if (options.ecmaVersion >= 2015)
  338. options.ecmaVersion -= 2009
  339. if (options.allowReserved == null)
  340. options.allowReserved = options.ecmaVersion < 5
  341. if (isArray(options.onToken)) {
  342. var tokens = options.onToken
  343. options.onToken = function (token) { return tokens.push(token); }
  344. }
  345. if (isArray(options.onComment))
  346. options.onComment = pushComment(options, options.onComment)
  347. return options
  348. }
  349. function pushComment(options, array) {
  350. return function (block, text, start, end, startLoc, endLoc) {
  351. var comment = {
  352. type: block ? 'Block' : 'Line',
  353. value: text,
  354. start: start,
  355. end: end
  356. }
  357. if (options.locations)
  358. comment.loc = new SourceLocation(this, startLoc, endLoc)
  359. if (options.ranges)
  360. comment.range = [start, end]
  361. array.push(comment)
  362. }
  363. }
  364. // Registered plugins
  365. var plugins = {}
  366. function keywordRegexp(words) {
  367. return new RegExp("^(" + words.replace(/ /g, "|") + ")$")
  368. }
  369. var Parser = function Parser(options, input, startPos) {
  370. this.options = options = getOptions(options)
  371. this.sourceFile = options.sourceFile
  372. this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5])
  373. var reserved = ""
  374. if (!options.allowReserved) {
  375. for (var v = options.ecmaVersion;; v--)
  376. if (reserved = reservedWords[v]) break
  377. if (options.sourceType == "module") reserved += " await"
  378. }
  379. this.reservedWords = keywordRegexp(reserved)
  380. var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict
  381. this.reservedWordsStrict = keywordRegexp(reservedStrict)
  382. this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind)
  383. this.input = String(input)
  384. // Used to signal to callers of `readWord1` whether the word
  385. // contained any escape sequences. This is needed because words with
  386. // escape sequences must not be interpreted as keywords.
  387. this.containsEsc = false
  388. // Load plugins
  389. this.loadPlugins(options.plugins)
  390. // Set up token state
  391. // The current position of the tokenizer in the input.
  392. if (startPos) {
  393. this.pos = startPos
  394. this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1
  395. this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length
  396. } else {
  397. this.pos = this.lineStart = 0
  398. this.curLine = 1
  399. }
  400. // Properties of the current token:
  401. // Its type
  402. this.type = tt.eof
  403. // For tokens that include more information than their type, the value
  404. this.value = null
  405. // Its start and end offset
  406. this.start = this.end = this.pos
  407. // And, if locations are used, the {line, column} object
  408. // corresponding to those offsets
  409. this.startLoc = this.endLoc = this.curPosition()
  410. // Position information for the previous token
  411. this.lastTokEndLoc = this.lastTokStartLoc = null
  412. this.lastTokStart = this.lastTokEnd = this.pos
  413. // The context stack is used to superficially track syntactic
  414. // context to predict whether a regular expression is allowed in a
  415. // given position.
  416. this.context = this.initialContext()
  417. this.exprAllowed = true
  418. // Figure out if it's a module code.
  419. this.inModule = options.sourceType === "module"
  420. this.strict = this.inModule || this.strictDirective(this.pos)
  421. // Used to signify the start of a potential arrow function
  422. this.potentialArrowAt = -1
  423. // Flags to track whether we are in a function, a generator, an async function.
  424. this.inFunction = this.inGenerator = this.inAsync = false
  425. // Positions to delayed-check that yield/await does not exist in default parameters.
  426. this.yieldPos = this.awaitPos = 0
  427. // Labels in scope.
  428. this.labels = []
  429. // If enabled, skip leading hashbang line.
  430. if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!')
  431. this.skipLineComment(2)
  432. };
  433. // DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them
  434. Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) };
  435. Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) };
  436. Parser.prototype.extend = function extend (name, f) {
  437. this[name] = f(this[name])
  438. };
  439. Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {
  440. var this$1 = this;
  441. for (var name in pluginConfigs) {
  442. var plugin = plugins[name]
  443. if (!plugin) throw new Error("Plugin '" + name + "' not found")
  444. plugin(this$1, pluginConfigs[name])
  445. }
  446. };
  447. Parser.prototype.parse = function parse () {
  448. var node = this.options.program || this.startNode()
  449. this.nextToken()
  450. return this.parseTopLevel(node)
  451. };
  452. var pp = Parser.prototype
  453. // ## Parser utilities
  454. var literal = /^(?:'((?:[^\']|\.)*)'|"((?:[^\"]|\.)*)"|;)/
  455. pp.strictDirective = function(start) {
  456. var this$1 = this;
  457. for (;;) {
  458. skipWhiteSpace.lastIndex = start
  459. start += skipWhiteSpace.exec(this$1.input)[0].length
  460. var match = literal.exec(this$1.input.slice(start))
  461. if (!match) return false
  462. if ((match[1] || match[2]) == "use strict") return true
  463. start += match[0].length
  464. }
  465. }
  466. // Predicate that tests whether the next token is of the given
  467. // type, and if yes, consumes it as a side effect.
  468. pp.eat = function(type) {
  469. if (this.type === type) {
  470. this.next()
  471. return true
  472. } else {
  473. return false
  474. }
  475. }
  476. // Tests whether parsed token is a contextual keyword.
  477. pp.isContextual = function(name) {
  478. return this.type === tt.name && this.value === name
  479. }
  480. // Consumes contextual keyword if possible.
  481. pp.eatContextual = function(name) {
  482. return this.value === name && this.eat(tt.name)
  483. }
  484. // Asserts that following token is given contextual keyword.
  485. pp.expectContextual = function(name) {
  486. if (!this.eatContextual(name)) this.unexpected()
  487. }
  488. // Test whether a semicolon can be inserted at the current position.
  489. pp.canInsertSemicolon = function() {
  490. return this.type === tt.eof ||
  491. this.type === tt.braceR ||
  492. lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
  493. }
  494. pp.insertSemicolon = function() {
  495. if (this.canInsertSemicolon()) {
  496. if (this.options.onInsertedSemicolon)
  497. this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc)
  498. return true
  499. }
  500. }
  501. // Consume a semicolon, or, failing that, see if we are allowed to
  502. // pretend that there is a semicolon at this position.
  503. pp.semicolon = function() {
  504. if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected()
  505. }
  506. pp.afterTrailingComma = function(tokType, notNext) {
  507. if (this.type == tokType) {
  508. if (this.options.onTrailingComma)
  509. this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc)
  510. if (!notNext)
  511. this.next()
  512. return true
  513. }
  514. }
  515. // Expect a token of a given type. If found, consume it, otherwise,
  516. // raise an unexpected token error.
  517. pp.expect = function(type) {
  518. this.eat(type) || this.unexpected()
  519. }
  520. // Raise an unexpected token error.
  521. pp.unexpected = function(pos) {
  522. this.raise(pos != null ? pos : this.start, "Unexpected token")
  523. }
  524. var DestructuringErrors = function DestructuringErrors() {
  525. this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = -1
  526. };
  527. pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
  528. if (!refDestructuringErrors) return
  529. if (refDestructuringErrors.trailingComma > -1)
  530. this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element")
  531. var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind
  532. if (parens > -1) this.raiseRecoverable(parens, "Parenthesized pattern")
  533. }
  534. pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
  535. var pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1
  536. if (!andThrow) return pos >= 0
  537. if (pos > -1) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns")
  538. }
  539. pp.checkYieldAwaitInDefaultParams = function() {
  540. if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
  541. this.raise(this.yieldPos, "Yield expression cannot be a default value")
  542. if (this.awaitPos)
  543. this.raise(this.awaitPos, "Await expression cannot be a default value")
  544. }
  545. pp.isSimpleAssignTarget = function(expr) {
  546. if (expr.type === "ParenthesizedExpression")
  547. return this.isSimpleAssignTarget(expr.expression)
  548. return expr.type === "Identifier" || expr.type === "MemberExpression"
  549. }
  550. var pp$1 = Parser.prototype
  551. // ### Statement parsing
  552. // Parse a program. Initializes the parser, reads any number of
  553. // statements, and wraps them in a Program node. Optionally takes a
  554. // `program` argument. If present, the statements will be appended
  555. // to its body instead of creating a new node.
  556. pp$1.parseTopLevel = function(node) {
  557. var this$1 = this;
  558. var exports = {}
  559. if (!node.body) node.body = []
  560. while (this.type !== tt.eof) {
  561. var stmt = this$1.parseStatement(true, true, exports)
  562. node.body.push(stmt)
  563. }
  564. this.next()
  565. if (this.options.ecmaVersion >= 6) {
  566. node.sourceType = this.options.sourceType
  567. }
  568. return this.finishNode(node, "Program")
  569. }
  570. var loopLabel = {kind: "loop"};
  571. var switchLabel = {kind: "switch"};
  572. pp$1.isLet = function() {
  573. if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false
  574. skipWhiteSpace.lastIndex = this.pos
  575. var skip = skipWhiteSpace.exec(this.input)
  576. var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next)
  577. if (nextCh === 91 || nextCh == 123) return true // '{' and '['
  578. if (isIdentifierStart(nextCh, true)) {
  579. for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {}
  580. var ident = this.input.slice(next, pos)
  581. if (!this.isKeyword(ident)) return true
  582. }
  583. return false
  584. }
  585. // check 'async [no LineTerminator here] function'
  586. // - 'async /*foo*/ function' is OK.
  587. // - 'async /*\n*/ function' is invalid.
  588. pp$1.isAsyncFunction = function() {
  589. if (this.type !== tt.name || this.options.ecmaVersion < 8 || this.value != "async")
  590. return false
  591. skipWhiteSpace.lastIndex = this.pos
  592. var skip = skipWhiteSpace.exec(this.input)
  593. var next = this.pos + skip[0].length
  594. return !lineBreak.test(this.input.slice(this.pos, next)) &&
  595. this.input.slice(next, next + 8) === "function" &&
  596. (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
  597. }
  598. // Parse a single statement.
  599. //
  600. // If expecting a statement and finding a slash operator, parse a
  601. // regular expression literal. This is to handle cases like
  602. // `if (foo) /blah/.exec(foo)`, where looking at the previous token
  603. // does not help.
  604. pp$1.parseStatement = function(declaration, topLevel, exports) {
  605. var starttype = this.type, node = this.startNode(), kind
  606. if (this.isLet()) {
  607. starttype = tt._var
  608. kind = "let"
  609. }
  610. // Most types of statements are recognized by the keyword they
  611. // start with. Many are trivial to parse, some require a bit of
  612. // complexity.
  613. switch (starttype) {
  614. case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
  615. case tt._debugger: return this.parseDebuggerStatement(node)
  616. case tt._do: return this.parseDoStatement(node)
  617. case tt._for: return this.parseForStatement(node)
  618. case tt._function:
  619. if (!declaration && this.options.ecmaVersion >= 6) this.unexpected()
  620. return this.parseFunctionStatement(node, false)
  621. case tt._class:
  622. if (!declaration) this.unexpected()
  623. return this.parseClass(node, true)
  624. case tt._if: return this.parseIfStatement(node)
  625. case tt._return: return this.parseReturnStatement(node)
  626. case tt._switch: return this.parseSwitchStatement(node)
  627. case tt._throw: return this.parseThrowStatement(node)
  628. case tt._try: return this.parseTryStatement(node)
  629. case tt._const: case tt._var:
  630. kind = kind || this.value
  631. if (!declaration && kind != "var") this.unexpected()
  632. return this.parseVarStatement(node, kind)
  633. case tt._while: return this.parseWhileStatement(node)
  634. case tt._with: return this.parseWithStatement(node)
  635. case tt.braceL: return this.parseBlock()
  636. case tt.semi: return this.parseEmptyStatement(node)
  637. case tt._export:
  638. case tt._import:
  639. if (!this.options.allowImportExportEverywhere) {
  640. if (!topLevel)
  641. this.raise(this.start, "'import' and 'export' may only appear at the top level")
  642. if (!this.inModule)
  643. this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'")
  644. }
  645. return starttype === tt._import ? this.parseImport(node) : this.parseExport(node, exports)
  646. // If the statement does not start with a statement keyword or a
  647. // brace, it's an ExpressionStatement or LabeledStatement. We
  648. // simply start parsing an expression, and afterwards, if the
  649. // next token is a colon and the expression was a simple
  650. // Identifier node, we switch to interpreting it as a label.
  651. default:
  652. if (this.isAsyncFunction() && declaration) {
  653. this.next()
  654. return this.parseFunctionStatement(node, true)
  655. }
  656. var maybeName = this.value, expr = this.parseExpression()
  657. if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon))
  658. return this.parseLabeledStatement(node, maybeName, expr)
  659. else return this.parseExpressionStatement(node, expr)
  660. }
  661. }
  662. pp$1.parseBreakContinueStatement = function(node, keyword) {
  663. var this$1 = this;
  664. var isBreak = keyword == "break"
  665. this.next()
  666. if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null
  667. else if (this.type !== tt.name) this.unexpected()
  668. else {
  669. node.label = this.parseIdent()
  670. this.semicolon()
  671. }
  672. // Verify that there is an actual destination to break or
  673. // continue to.
  674. for (var i = 0; i < this.labels.length; ++i) {
  675. var lab = this$1.labels[i]
  676. if (node.label == null || lab.name === node.label.name) {
  677. if (lab.kind != null && (isBreak || lab.kind === "loop")) break
  678. if (node.label && isBreak) break
  679. }
  680. }
  681. if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword)
  682. return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
  683. }
  684. pp$1.parseDebuggerStatement = function(node) {
  685. this.next()
  686. this.semicolon()
  687. return this.finishNode(node, "DebuggerStatement")
  688. }
  689. pp$1.parseDoStatement = function(node) {
  690. this.next()
  691. this.labels.push(loopLabel)
  692. node.body = this.parseStatement(false)
  693. this.labels.pop()
  694. this.expect(tt._while)
  695. node.test = this.parseParenExpression()
  696. if (this.options.ecmaVersion >= 6)
  697. this.eat(tt.semi)
  698. else
  699. this.semicolon()
  700. return this.finishNode(node, "DoWhileStatement")
  701. }
  702. // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
  703. // loop is non-trivial. Basically, we have to parse the init `var`
  704. // statement or expression, disallowing the `in` operator (see
  705. // the second parameter to `parseExpression`), and then check
  706. // whether the next token is `in` or `of`. When there is no init
  707. // part (semicolon immediately after the opening parenthesis), it
  708. // is a regular `for` loop.
  709. pp$1.parseForStatement = function(node) {
  710. this.next()
  711. this.labels.push(loopLabel)
  712. this.expect(tt.parenL)
  713. if (this.type === tt.semi) return this.parseFor(node, null)
  714. var isLet = this.isLet()
  715. if (this.type === tt._var || this.type === tt._const || isLet) {
  716. var init$1 = this.startNode(), kind = isLet ? "let" : this.value
  717. this.next()
  718. this.parseVar(init$1, true, kind)
  719. this.finishNode(init$1, "VariableDeclaration")
  720. if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 &&
  721. !(kind !== "var" && init$1.declarations[0].init))
  722. return this.parseForIn(node, init$1)
  723. return this.parseFor(node, init$1)
  724. }
  725. var refDestructuringErrors = new DestructuringErrors
  726. var init = this.parseExpression(true, refDestructuringErrors)
  727. if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
  728. this.toAssignable(init)
  729. this.checkLVal(init)
  730. this.checkPatternErrors(refDestructuringErrors, true)
  731. return this.parseForIn(node, init)
  732. } else {
  733. this.checkExpressionErrors(refDestructuringErrors, true)
  734. }
  735. return this.parseFor(node, init)
  736. }
  737. pp$1.parseFunctionStatement = function(node, isAsync) {
  738. this.next()
  739. return this.parseFunction(node, true, false, isAsync)
  740. }
  741. pp$1.isFunction = function() {
  742. return this.type === tt._function || this.isAsyncFunction()
  743. }
  744. pp$1.parseIfStatement = function(node) {
  745. this.next()
  746. node.test = this.parseParenExpression()
  747. // allow function declarations in branches, but only in non-strict mode
  748. node.consequent = this.parseStatement(!this.strict && this.isFunction())
  749. node.alternate = this.eat(tt._else) ? this.parseStatement(!this.strict && this.isFunction()) : null
  750. return this.finishNode(node, "IfStatement")
  751. }
  752. pp$1.parseReturnStatement = function(node) {
  753. if (!this.inFunction && !this.options.allowReturnOutsideFunction)
  754. this.raise(this.start, "'return' outside of function")
  755. this.next()
  756. // In `return` (and `break`/`continue`), the keywords with
  757. // optional arguments, we eagerly look for a semicolon or the
  758. // possibility to insert one.
  759. if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null
  760. else { node.argument = this.parseExpression(); this.semicolon() }
  761. return this.finishNode(node, "ReturnStatement")
  762. }
  763. pp$1.parseSwitchStatement = function(node) {
  764. var this$1 = this;
  765. this.next()
  766. node.discriminant = this.parseParenExpression()
  767. node.cases = []
  768. this.expect(tt.braceL)
  769. this.labels.push(switchLabel)
  770. // Statements under must be grouped (by label) in SwitchCase
  771. // nodes. `cur` is used to keep the node that we are currently
  772. // adding statements to.
  773. for (var cur, sawDefault = false; this.type != tt.braceR;) {
  774. if (this$1.type === tt._case || this$1.type === tt._default) {
  775. var isCase = this$1.type === tt._case
  776. if (cur) this$1.finishNode(cur, "SwitchCase")
  777. node.cases.push(cur = this$1.startNode())
  778. cur.consequent = []
  779. this$1.next()
  780. if (isCase) {
  781. cur.test = this$1.parseExpression()
  782. } else {
  783. if (sawDefault) this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses")
  784. sawDefault = true
  785. cur.test = null
  786. }
  787. this$1.expect(tt.colon)
  788. } else {
  789. if (!cur) this$1.unexpected()
  790. cur.consequent.push(this$1.parseStatement(true))
  791. }
  792. }
  793. if (cur) this.finishNode(cur, "SwitchCase")
  794. this.next() // Closing brace
  795. this.labels.pop()
  796. return this.finishNode(node, "SwitchStatement")
  797. }
  798. pp$1.parseThrowStatement = function(node) {
  799. this.next()
  800. if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
  801. this.raise(this.lastTokEnd, "Illegal newline after throw")
  802. node.argument = this.parseExpression()
  803. this.semicolon()
  804. return this.finishNode(node, "ThrowStatement")
  805. }
  806. // Reused empty array added for node fields that are always empty.
  807. var empty = []
  808. pp$1.parseTryStatement = function(node) {
  809. this.next()
  810. node.block = this.parseBlock()
  811. node.handler = null
  812. if (this.type === tt._catch) {
  813. var clause = this.startNode()
  814. this.next()
  815. this.expect(tt.parenL)
  816. clause.param = this.parseBindingAtom()
  817. this.checkLVal(clause.param, true)
  818. this.expect(tt.parenR)
  819. clause.body = this.parseBlock()
  820. node.handler = this.finishNode(clause, "CatchClause")
  821. }
  822. node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null
  823. if (!node.handler && !node.finalizer)
  824. this.raise(node.start, "Missing catch or finally clause")
  825. return this.finishNode(node, "TryStatement")
  826. }
  827. pp$1.parseVarStatement = function(node, kind) {
  828. this.next()
  829. this.parseVar(node, false, kind)
  830. this.semicolon()
  831. return this.finishNode(node, "VariableDeclaration")
  832. }
  833. pp$1.parseWhileStatement = function(node) {
  834. this.next()
  835. node.test = this.parseParenExpression()
  836. this.labels.push(loopLabel)
  837. node.body = this.parseStatement(false)
  838. this.labels.pop()
  839. return this.finishNode(node, "WhileStatement")
  840. }
  841. pp$1.parseWithStatement = function(node) {
  842. if (this.strict) this.raise(this.start, "'with' in strict mode")
  843. this.next()
  844. node.object = this.parseParenExpression()
  845. node.body = this.parseStatement(false)
  846. return this.finishNode(node, "WithStatement")
  847. }
  848. pp$1.parseEmptyStatement = function(node) {
  849. this.next()
  850. return this.finishNode(node, "EmptyStatement")
  851. }
  852. pp$1.parseLabeledStatement = function(node, maybeName, expr) {
  853. var this$1 = this;
  854. for (var i = 0; i < this.labels.length; ++i)
  855. if (this$1.labels[i].name === maybeName) this$1.raise(expr.start, "Label '" + maybeName + "' is already declared")
  856. var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null
  857. for (var i$1 = this.labels.length - 1; i$1 >= 0; i$1--) {
  858. var label = this$1.labels[i$1]
  859. if (label.statementStart == node.start) {
  860. label.statementStart = this$1.start
  861. label.kind = kind
  862. } else break
  863. }
  864. this.labels.push({name: maybeName, kind: kind, statementStart: this.start})
  865. node.body = this.parseStatement(true)
  866. if (node.body.type == "ClassDeclaration" ||
  867. node.body.type == "VariableDeclaration" && (this.strict || node.body.kind != "var") ||
  868. node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator))
  869. this.raiseRecoverable(node.body.start, "Invalid labeled declaration")
  870. this.labels.pop()
  871. node.label = expr
  872. return this.finishNode(node, "LabeledStatement")
  873. }
  874. pp$1.parseExpressionStatement = function(node, expr) {
  875. node.expression = expr
  876. this.semicolon()
  877. return this.finishNode(node, "ExpressionStatement")
  878. }
  879. // Parse a semicolon-enclosed block of statements, handling `"use
  880. // strict"` declarations when `allowStrict` is true (used for
  881. // function bodies).
  882. pp$1.parseBlock = function() {
  883. var this$1 = this;
  884. var node = this.startNode()
  885. node.body = []
  886. this.expect(tt.braceL)
  887. while (!this.eat(tt.braceR)) {
  888. var stmt = this$1.parseStatement(true)
  889. node.body.push(stmt)
  890. }
  891. return this.finishNode(node, "BlockStatement")
  892. }
  893. // Parse a regular `for` loop. The disambiguation code in
  894. // `parseStatement` will already have parsed the init statement or
  895. // expression.
  896. pp$1.parseFor = function(node, init) {
  897. node.init = init
  898. this.expect(tt.semi)
  899. node.test = this.type === tt.semi ? null : this.parseExpression()
  900. this.expect(tt.semi)
  901. node.update = this.type === tt.parenR ? null : this.parseExpression()
  902. this.expect(tt.parenR)
  903. node.body = this.parseStatement(false)
  904. this.labels.pop()
  905. return this.finishNode(node, "ForStatement")
  906. }
  907. // Parse a `for`/`in` and `for`/`of` loop, which are almost
  908. // same from parser's perspective.
  909. pp$1.parseForIn = function(node, init) {
  910. var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement"
  911. this.next()
  912. node.left = init
  913. node.right = this.parseExpression()
  914. this.expect(tt.parenR)
  915. node.body = this.parseStatement(false)
  916. this.labels.pop()
  917. return this.finishNode(node, type)
  918. }
  919. // Parse a list of variable declarations.
  920. pp$1.parseVar = function(node, isFor, kind) {
  921. var this$1 = this;
  922. node.declarations = []
  923. node.kind = kind
  924. for (;;) {
  925. var decl = this$1.startNode()
  926. this$1.parseVarId(decl)
  927. if (this$1.eat(tt.eq)) {
  928. decl.init = this$1.parseMaybeAssign(isFor)
  929. } else if (kind === "const" && !(this$1.type === tt._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) {
  930. this$1.unexpected()
  931. } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === tt._in || this$1.isContextual("of")))) {
  932. this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value")
  933. } else {
  934. decl.init = null
  935. }
  936. node.declarations.push(this$1.finishNode(decl, "VariableDeclarator"))
  937. if (!this$1.eat(tt.comma)) break
  938. }
  939. return node
  940. }
  941. pp$1.parseVarId = function(decl) {
  942. decl.id = this.parseBindingAtom()
  943. this.checkLVal(decl.id, true)
  944. }
  945. // Parse a function declaration or literal (depending on the
  946. // `isStatement` parameter).
  947. pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) {
  948. this.initFunction(node)
  949. if (this.options.ecmaVersion >= 6 && !isAsync)
  950. node.generator = this.eat(tt.star)
  951. if (this.options.ecmaVersion >= 8)
  952. node.async = !!isAsync
  953. if (isStatement == null)
  954. isStatement = this.type == tt.name
  955. if (isStatement)
  956. node.id = this.parseIdent()
  957. var oldInGen = this.inGenerator, oldInAsync = this.inAsync,
  958. oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction
  959. this.inGenerator = node.generator
  960. this.inAsync = node.async
  961. this.yieldPos = 0
  962. this.awaitPos = 0
  963. this.inFunction = true
  964. if (!isStatement && this.type === tt.name)
  965. node.id = this.parseIdent()
  966. this.parseFunctionParams(node)
  967. this.parseFunctionBody(node, allowExpressionBody)
  968. this.inGenerator = oldInGen
  969. this.inAsync = oldInAsync
  970. this.yieldPos = oldYieldPos
  971. this.awaitPos = oldAwaitPos
  972. this.inFunction = oldInFunc
  973. return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
  974. }
  975. pp$1.parseFunctionParams = function(node) {
  976. this.expect(tt.parenL)
  977. node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8, true)
  978. this.checkYieldAwaitInDefaultParams()
  979. }
  980. // Parse a class declaration or literal (depending on the
  981. // `isStatement` parameter).
  982. pp$1.parseClass = function(node, isStatement) {
  983. var this$1 = this;
  984. this.next()
  985. if (isStatement == null) isStatement = this.type === tt.name
  986. this.parseClassId(node, isStatement)
  987. this.parseClassSuper(node)
  988. var classBody = this.startNode()
  989. var hadConstructor = false
  990. classBody.body = []
  991. this.expect(tt.braceL)
  992. while (!this.eat(tt.braceR)) {
  993. if (this$1.eat(tt.semi)) continue
  994. var method = this$1.startNode()
  995. var isGenerator = this$1.eat(tt.star)
  996. var isAsync = false
  997. var isMaybeStatic = this$1.type === tt.name && this$1.value === "static"
  998. this$1.parsePropertyName(method)
  999. method.static = isMaybeStatic && this$1.type !== tt.parenL
  1000. if (method.static) {
  1001. if (isGenerator) this$1.unexpected()
  1002. isGenerator = this$1.eat(tt.star)
  1003. this$1.parsePropertyName(method)
  1004. }
  1005. if (this$1.options.ecmaVersion >= 8 && !isGenerator && !method.computed &&
  1006. method.key.type === "Identifier" && method.key.name === "async" && this$1.type !== tt.parenL &&
  1007. !this$1.canInsertSemicolon()) {
  1008. isAsync = true
  1009. this$1.parsePropertyName(method)
  1010. }
  1011. method.kind = "method"
  1012. var isGetSet = false
  1013. if (!method.computed) {
  1014. var key = method.key;
  1015. if (!isGenerator && !isAsync && key.type === "Identifier" && this$1.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
  1016. isGetSet = true
  1017. method.kind = key.name
  1018. key = this$1.parsePropertyName(method)
  1019. }
  1020. if (!method.static && (key.type === "Identifier" && key.name === "constructor" ||
  1021. key.type === "Literal" && key.value === "constructor")) {
  1022. if (hadConstructor) this$1.raise(key.start, "Duplicate constructor in the same class")
  1023. if (isGetSet) this$1.raise(key.start, "Constructor can't have get/set modifier")
  1024. if (isGenerator) this$1.raise(key.start, "Constructor can't be a generator")
  1025. if (isAsync) this$1.raise(key.start, "Constructor can't be an async method")
  1026. method.kind = "constructor"
  1027. hadConstructor = true
  1028. }
  1029. }
  1030. this$1.parseClassMethod(classBody, method, isGenerator, isAsync)
  1031. if (isGetSet) {
  1032. var paramCount = method.kind === "get" ? 0 : 1
  1033. if (method.value.params.length !== paramCount) {
  1034. var start = method.value.start
  1035. if (method.kind === "get")
  1036. this$1.raiseRecoverable(start, "getter should have no params")
  1037. else
  1038. this$1.raiseRecoverable(start, "setter should have exactly one param")
  1039. } else {
  1040. if (method.kind === "set" && method.value.params[0].type === "RestElement")
  1041. this$1.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params")
  1042. }
  1043. }
  1044. }
  1045. node.body = this.finishNode(classBody, "ClassBody")
  1046. return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
  1047. }
  1048. pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) {
  1049. method.value = this.parseMethod(isGenerator, isAsync)
  1050. classBody.body.push(this.finishNode(method, "MethodDefinition"))
  1051. }
  1052. pp$1.parseClassId = function(node, isStatement) {
  1053. node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null
  1054. }
  1055. pp$1.parseClassSuper = function(node) {
  1056. node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null
  1057. }
  1058. // Parses module export declaration.
  1059. pp$1.parseExport = function(node, exports) {
  1060. var this$1 = this;
  1061. this.next()
  1062. // export * from '...'
  1063. if (this.eat(tt.star)) {
  1064. this.expectContextual("from")
  1065. node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected()
  1066. this.semicolon()
  1067. return this.finishNode(node, "ExportAllDeclaration")
  1068. }
  1069. if (this.eat(tt._default)) { // export default ...
  1070. this.checkExport(exports, "default", this.lastTokStart)
  1071. var isAsync
  1072. if (this.type === tt._function || (isAsync = this.isAsyncFunction())) {
  1073. var fNode = this.startNode()
  1074. this.next()
  1075. if (isAsync) this.next()
  1076. node.declaration = this.parseFunction(fNode, null, false, isAsync)
  1077. } else if (this.type === tt._class) {
  1078. var cNode = this.startNode()
  1079. node.declaration = this.parseClass(cNode, null)
  1080. } else {
  1081. node.declaration = this.parseMaybeAssign()
  1082. this.semicolon()
  1083. }
  1084. return this.finishNode(node, "ExportDefaultDeclaration")
  1085. }
  1086. // export var|const|let|function|class ...
  1087. if (this.shouldParseExportStatement()) {
  1088. node.declaration = this.parseStatement(true)
  1089. if (node.declaration.type === "VariableDeclaration")
  1090. this.checkVariableExport(exports, node.declaration.declarations)
  1091. else
  1092. this.checkExport(exports, node.declaration.id.name, node.declaration.id.start)
  1093. node.specifiers = []
  1094. node.source = null
  1095. } else { // export { x, y as z } [from '...']
  1096. node.declaration = null
  1097. node.specifiers = this.parseExportSpecifiers(exports)
  1098. if (this.eatContextual("from")) {
  1099. node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected()
  1100. } else {
  1101. // check for keywords used as local names
  1102. for (var i = 0; i < node.specifiers.length; i++) {
  1103. if (this$1.keywords.test(node.specifiers[i].local.name) || this$1.reservedWords.test(node.specifiers[i].local.name)) {
  1104. this$1.unexpected(node.specifiers[i].local.start)
  1105. }
  1106. }
  1107. node.source = null
  1108. }
  1109. this.semicolon()
  1110. }
  1111. return this.finishNode(node, "ExportNamedDeclaration")
  1112. }
  1113. pp$1.checkExport = function(exports, name, pos) {
  1114. if (!exports) return
  1115. if (Object.prototype.hasOwnProperty.call(exports, name))
  1116. this.raiseRecoverable(pos, "Duplicate export '" + name + "'")
  1117. exports[name] = true
  1118. }
  1119. pp$1.checkPatternExport = function(exports, pat) {
  1120. var this$1 = this;
  1121. var type = pat.type
  1122. if (type == "Identifier")
  1123. this.checkExport(exports, pat.name, pat.start)
  1124. else if (type == "ObjectPattern")
  1125. for (var i = 0; i < pat.properties.length; ++i)
  1126. this$1.checkPatternExport(exports, pat.properties[i].value)
  1127. else if (type == "ArrayPattern")
  1128. for (var i$1 = 0; i$1 < pat.elements.length; ++i$1) {
  1129. var elt = pat.elements[i$1]
  1130. if (elt) this$1.checkPatternExport(exports, elt)
  1131. }
  1132. else if (type == "AssignmentPattern")
  1133. this.checkPatternExport(exports, pat.left)
  1134. else if (type == "ParenthesizedExpression")
  1135. this.checkPatternExport(exports, pat.expression)
  1136. }
  1137. pp$1.checkVariableExport = function(exports, decls) {
  1138. var this$1 = this;
  1139. if (!exports) return
  1140. for (var i = 0; i < decls.length; i++)
  1141. this$1.checkPatternExport(exports, decls[i].id)
  1142. }
  1143. pp$1.shouldParseExportStatement = function() {
  1144. return this.type.keyword === "var"
  1145. || this.type.keyword === "const"
  1146. || this.type.keyword === "class"
  1147. || this.type.keyword === "function"
  1148. || this.isLet()
  1149. || this.isAsyncFunction()
  1150. }
  1151. // Parses a comma-separated list of module exports.
  1152. pp$1.parseExportSpecifiers = function(exports) {
  1153. var this$1 = this;
  1154. var nodes = [], first = true
  1155. // export { x, y as z } [from '...']
  1156. this.expect(tt.braceL)
  1157. while (!this.eat(tt.braceR)) {
  1158. if (!first) {
  1159. this$1.expect(tt.comma)
  1160. if (this$1.afterTrailingComma(tt.braceR)) break
  1161. } else first = false
  1162. var node = this$1.startNode()
  1163. node.local = this$1.parseIdent(true)
  1164. node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local
  1165. this$1.checkExport(exports, node.exported.name, node.exported.start)
  1166. nodes.push(this$1.finishNode(node, "ExportSpecifier"))
  1167. }
  1168. return nodes
  1169. }
  1170. // Parses import declaration.
  1171. pp$1.parseImport = function(node) {
  1172. this.next()
  1173. // import '...'
  1174. if (this.type === tt.string) {
  1175. node.specifiers = empty
  1176. node.source = this.parseExprAtom()
  1177. } else {
  1178. node.specifiers = this.parseImportSpecifiers()
  1179. this.expectContextual("from")
  1180. node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected()
  1181. }
  1182. this.semicolon()
  1183. return this.finishNode(node, "ImportDeclaration")
  1184. }
  1185. // Parses a comma-separated list of module imports.
  1186. pp$1.parseImportSpecifiers = function() {
  1187. var this$1 = this;
  1188. var nodes = [], first = true
  1189. if (this.type === tt.name) {
  1190. // import defaultObj, { x, y as z } from '...'
  1191. var node = this.startNode()
  1192. node.local = this.parseIdent()
  1193. this.checkLVal(node.local, true)
  1194. nodes.push(this.finishNode(node, "ImportDefaultSpecifier"))
  1195. if (!this.eat(tt.comma)) return nodes
  1196. }
  1197. if (this.type === tt.star) {
  1198. var node$1 = this.startNode()
  1199. this.next()
  1200. this.expectContextual("as")
  1201. node$1.local = this.parseIdent()
  1202. this.checkLVal(node$1.local, true)
  1203. nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"))
  1204. return nodes
  1205. }
  1206. this.expect(tt.braceL)
  1207. while (!this.eat(tt.braceR)) {
  1208. if (!first) {
  1209. this$1.expect(tt.comma)
  1210. if (this$1.afterTrailingComma(tt.braceR)) break
  1211. } else first = false
  1212. var node$2 = this$1.startNode()
  1213. node$2.imported = this$1.parseIdent(true)
  1214. if (this$1.eatContextual("as")) {
  1215. node$2.local = this$1.parseIdent()
  1216. } else {
  1217. node$2.local = node$2.imported
  1218. if (this$1.isKeyword(node$2.local.name)) this$1.unexpected(node$2.local.start)
  1219. if (this$1.reservedWordsStrict.test(node$2.local.name)) this$1.raiseRecoverable(node$2.local.start, "The keyword '" + node$2.local.name + "' is reserved")
  1220. }
  1221. this$1.checkLVal(node$2.local, true)
  1222. nodes.push(this$1.finishNode(node$2, "ImportSpecifier"))
  1223. }
  1224. return nodes
  1225. }
  1226. var pp$2 = Parser.prototype
  1227. // Convert existing expression atom to assignable pattern
  1228. // if possible.
  1229. pp$2.toAssignable = function(node, isBinding) {
  1230. var this$1 = this;
  1231. if (this.options.ecmaVersion >= 6 && node) {
  1232. switch (node.type) {
  1233. case "Identifier":
  1234. if (this.inAsync && node.name === "await")
  1235. this.raise(node.start, "Can not use 'await' as identifier inside an async function")
  1236. break
  1237. case "ObjectPattern":
  1238. case "ArrayPattern":
  1239. break
  1240. case "ObjectExpression":
  1241. node.type = "ObjectPattern"
  1242. for (var i = 0; i < node.properties.length; i++) {
  1243. var prop = node.properties[i]
  1244. if (prop.kind !== "init") this$1.raise(prop.key.start, "Object pattern can't contain getter or setter")
  1245. this$1.toAssignable(prop.value, isBinding)
  1246. }
  1247. break
  1248. case "ArrayExpression":
  1249. node.type = "ArrayPattern"
  1250. this.toAssignableList(node.elements, isBinding)
  1251. break
  1252. case "AssignmentExpression":
  1253. if (node.operator === "=") {
  1254. node.type = "AssignmentPattern"
  1255. delete node.operator
  1256. this.toAssignable(node.left, isBinding)
  1257. // falls through to AssignmentPattern
  1258. } else {
  1259. this.raise(node.left.end, "Only '=' operator can be used for specifying default value.")
  1260. break
  1261. }
  1262. case "AssignmentPattern":
  1263. break
  1264. case "ParenthesizedExpression":
  1265. node.expression = this.toAssignable(node.expression, isBinding)
  1266. break
  1267. case "MemberExpression":
  1268. if (!isBinding) break
  1269. default:
  1270. this.raise(node.start, "Assigning to rvalue")
  1271. }
  1272. }
  1273. return node
  1274. }
  1275. // Convert list of expression atoms to binding list.
  1276. pp$2.toAssignableList = function(exprList, isBinding) {
  1277. var this$1 = this;
  1278. var end = exprList.length
  1279. if (end) {
  1280. var last = exprList[end - 1]
  1281. if (last && last.type == "RestElement") {
  1282. --end
  1283. } else if (last && last.type == "SpreadElement") {
  1284. last.type = "RestElement"
  1285. var arg = last.argument
  1286. this.toAssignable(arg, isBinding)
  1287. if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern")
  1288. this.unexpected(arg.start)
  1289. --end
  1290. }
  1291. if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
  1292. this.unexpected(last.argument.start)
  1293. }
  1294. for (var i = 0; i < end; i++) {
  1295. var elt = exprList[i]
  1296. if (elt) this$1.toAssignable(elt, isBinding)
  1297. }
  1298. return exprList
  1299. }
  1300. // Parses spread element.
  1301. pp$2.parseSpread = function(refDestructuringErrors) {
  1302. var node = this.startNode()
  1303. this.next()
  1304. node.argument = this.parseMaybeAssign(false, refDestructuringErrors)
  1305. return this.finishNode(node, "SpreadElement")
  1306. }
  1307. pp$2.parseRest = function(allowNonIdent) {
  1308. var node = this.startNode()
  1309. this.next()
  1310. // RestElement inside of a function parameter must be an identifier
  1311. if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected()
  1312. else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected()
  1313. return this.finishNode(node, "RestElement")
  1314. }
  1315. // Parses lvalue (assignable) atom.
  1316. pp$2.parseBindingAtom = function() {
  1317. if (this.options.ecmaVersion < 6) return this.parseIdent()
  1318. switch (this.type) {
  1319. case tt.name:
  1320. return this.parseIdent()
  1321. case tt.bracketL:
  1322. var node = this.startNode()
  1323. this.next()
  1324. node.elements = this.parseBindingList(tt.bracketR, true, true)
  1325. return this.finishNode(node, "ArrayPattern")
  1326. case tt.braceL:
  1327. return this.parseObj(true)
  1328. default:
  1329. this.unexpected()
  1330. }
  1331. }
  1332. pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) {
  1333. var this$1 = this;
  1334. var elts = [], first = true
  1335. while (!this.eat(close)) {
  1336. if (first) first = false
  1337. else this$1.expect(tt.comma)
  1338. if (allowEmpty && this$1.type === tt.comma) {
  1339. elts.push(null)
  1340. } else if (allowTrailingComma && this$1.afterTrailingComma(close)) {
  1341. break
  1342. } else if (this$1.type === tt.ellipsis) {
  1343. var rest = this$1.parseRest(allowNonIdent)
  1344. this$1.parseBindingListItem(rest)
  1345. elts.push(rest)
  1346. if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element")
  1347. this$1.expect(close)
  1348. break
  1349. } else {
  1350. var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc)
  1351. this$1.parseBindingListItem(elem)
  1352. elts.push(elem)
  1353. }
  1354. }
  1355. return elts
  1356. }
  1357. pp$2.parseBindingListItem = function(param) {
  1358. return param
  1359. }
  1360. // Parses assignment pattern around given atom if possible.
  1361. pp$2.parseMaybeDefault = function(startPos, startLoc, left) {
  1362. left = left || this.parseBindingAtom()
  1363. if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left
  1364. var node = this.startNodeAt(startPos, startLoc)
  1365. node.left = left
  1366. node.right = this.parseMaybeAssign()
  1367. return this.finishNode(node, "AssignmentPattern")
  1368. }
  1369. // Verify that a node is an lval — something that can be assigned
  1370. // to.
  1371. pp$2.checkLVal = function(expr, isBinding, checkClashes) {
  1372. var this$1 = this;
  1373. switch (expr.type) {
  1374. case "Identifier":
  1375. if (this.strict && this.reservedWordsStrictBind.test(expr.name))
  1376. this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode")
  1377. if (checkClashes) {
  1378. if (has(checkClashes, expr.name))
  1379. this.raiseRecoverable(expr.start, "Argument name clash")
  1380. checkClashes[expr.name] = true
  1381. }
  1382. break
  1383. case "MemberExpression":
  1384. if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression")
  1385. break
  1386. case "ObjectPattern":
  1387. for (var i = 0; i < expr.properties.length; i++)
  1388. this$1.checkLVal(expr.properties[i].value, isBinding, checkClashes)
  1389. break
  1390. case "ArrayPattern":
  1391. for (var i$1 = 0; i$1 < expr.elements.length; i$1++) {
  1392. var elem = expr.elements[i$1]
  1393. if (elem) this$1.checkLVal(elem, isBinding, checkClashes)
  1394. }
  1395. break
  1396. case "AssignmentPattern":
  1397. this.checkLVal(expr.left, isBinding, checkClashes)
  1398. break
  1399. case "RestElement":
  1400. this.checkLVal(expr.argument, isBinding, checkClashes)
  1401. break
  1402. case "ParenthesizedExpression":
  1403. this.checkLVal(expr.expression, isBinding, checkClashes)
  1404. break
  1405. default:
  1406. this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue")
  1407. }
  1408. }
  1409. // A recursive descent parser operates by defining functions for all
  1410. // syntactic elements, and recursively calling those, each function
  1411. // advancing the input stream and returning an AST node. Precedence
  1412. // of constructs (for example, the fact that `!x[1]` means `!(x[1])`
  1413. // instead of `(!x)[1]` is handled by the fact that the parser
  1414. // function that parses unary prefix operators is called first, and
  1415. // in turn calls the function that parses `[]` subscripts — that
  1416. // way, it'll receive the node for `x[1]` already parsed, and wraps
  1417. // *that* in the unary operator node.
  1418. //
  1419. // Acorn uses an [operator precedence parser][opp] to handle binary
  1420. // operator precedence, because it is much more compact than using
  1421. // the technique outlined above, which uses different, nesting
  1422. // functions to specify precedence, for all of the ten binary
  1423. // precedence levels that JavaScript defines.
  1424. //
  1425. // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
  1426. var pp$3 = Parser.prototype
  1427. // Check if property name clashes with already added.
  1428. // Object/class getters and setters are not allowed to clash —
  1429. // either with each other or with an init property — and in
  1430. // strict mode, init properties are also not allowed to be repeated.
  1431. pp$3.checkPropClash = function(prop, propHash) {
  1432. if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
  1433. return
  1434. var key = prop.key;
  1435. var name
  1436. switch (key.type) {
  1437. case "Identifier": name = key.name; break
  1438. case "Literal": name = String(key.value); break
  1439. default: return
  1440. }
  1441. var kind = prop.kind;
  1442. if (this.options.ecmaVersion >= 6) {
  1443. if (name === "__proto__" && kind === "init") {
  1444. if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property")
  1445. propHash.proto = true
  1446. }
  1447. return
  1448. }
  1449. name = "$" + name
  1450. var other = propHash[name]
  1451. if (other) {
  1452. var isGetSet = kind !== "init"
  1453. if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init))
  1454. this.raiseRecoverable(key.start, "Redefinition of property")
  1455. } else {
  1456. other = propHash[name] = {
  1457. init: false,
  1458. get: false,
  1459. set: false
  1460. }
  1461. }
  1462. other[kind] = true
  1463. }
  1464. // ### Expression parsing
  1465. // These nest, from the most general expression type at the top to
  1466. // 'atomic', nondivisible expression types at the bottom. Most of
  1467. // the functions will simply let the function(s) below them parse,
  1468. // and, *if* the syntactic construct they handle is present, wrap
  1469. // the AST node that the inner parser gave them in another node.
  1470. // Parse a full expression. The optional arguments are used to
  1471. // forbid the `in` operator (in for loops initalization expressions)
  1472. // and provide reference for storing '=' operator inside shorthand
  1473. // property assignment in contexts where both object expression
  1474. // and object pattern might appear (so it's possible to raise
  1475. // delayed syntax error at correct position).
  1476. pp$3.parseExpression = function(noIn, refDestructuringErrors) {
  1477. var this$1 = this;
  1478. var startPos = this.start, startLoc = this.startLoc
  1479. var expr = this.parseMaybeAssign(noIn, refDestructuringErrors)
  1480. if (this.type === tt.comma) {
  1481. var node = this.startNodeAt(startPos, startLoc)
  1482. node.expressions = [expr]
  1483. while (this.eat(tt.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors))
  1484. return this.finishNode(node, "SequenceExpression")
  1485. }
  1486. return expr
  1487. }
  1488. // Parse an assignment expression. This includes applications of
  1489. // operators like `+=`.
  1490. pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
  1491. if (this.inGenerator && this.isContextual("yield")) return this.parseYield()
  1492. var ownDestructuringErrors = false, oldParenAssign = -1
  1493. if (refDestructuringErrors) {
  1494. oldParenAssign = refDestructuringErrors.parenthesizedAssign
  1495. refDestructuringErrors.parenthesizedAssign = -1
  1496. } else {
  1497. refDestructuringErrors = new DestructuringErrors
  1498. ownDestructuringErrors = true
  1499. }
  1500. var startPos = this.start, startLoc = this.startLoc
  1501. if (this.type == tt.parenL || this.type == tt.name)
  1502. this.potentialArrowAt = this.start
  1503. var left = this.parseMaybeConditional(noIn, refDestructuringErrors)
  1504. if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc)
  1505. if (this.type.isAssign) {
  1506. this.checkPatternErrors(refDestructuringErrors, true)
  1507. if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors)
  1508. var node = this.startNodeAt(startPos, startLoc)
  1509. node.operator = this.value
  1510. node.left = this.type === tt.eq ? this.toAssignable(left) : left
  1511. refDestructuringErrors.shorthandAssign = -1 // reset because shorthand default was used correctly
  1512. this.checkLVal(left)
  1513. this.next()
  1514. node.right = this.parseMaybeAssign(noIn)
  1515. return this.finishNode(node, "AssignmentExpression")
  1516. } else {
  1517. if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true)
  1518. }
  1519. if (oldParenAssign > -1) refDestructuringErrors.parenthesizedAssign = oldParenAssign
  1520. return left
  1521. }
  1522. // Parse a ternary conditional (`?:`) operator.
  1523. pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
  1524. var startPos = this.start, startLoc = this.startLoc
  1525. var expr = this.parseExprOps(noIn, refDestructuringErrors)
  1526. if (this.checkExpressionErrors(refDestructuringErrors)) return expr
  1527. if (this.eat(tt.question)) {
  1528. var node = this.startNodeAt(startPos, startLoc)
  1529. node.test = expr
  1530. node.consequent = this.parseMaybeAssign()
  1531. this.expect(tt.colon)
  1532. node.alternate = this.parseMaybeAssign(noIn)
  1533. return this.finishNode(node, "ConditionalExpression")
  1534. }
  1535. return expr
  1536. }
  1537. // Start the precedence parser.
  1538. pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
  1539. var startPos = this.start, startLoc = this.startLoc
  1540. var expr = this.parseMaybeUnary(refDestructuringErrors, false)
  1541. if (this.checkExpressionErrors(refDestructuringErrors)) return expr
  1542. return this.parseExprOp(expr, startPos, startLoc, -1, noIn)
  1543. }
  1544. // Parse binary operators with the operator precedence parsing
  1545. // algorithm. `left` is the left-hand side of the operator.
  1546. // `minPrec` provides context that allows the function to stop and
  1547. // defer further parser to one of its callers when it encounters an
  1548. // operator that has a lower precedence than the set it is parsing.
  1549. pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
  1550. var prec = this.type.binop
  1551. if (prec != null && (!noIn || this.type !== tt._in)) {
  1552. if (prec > minPrec) {
  1553. var logical = this.type === tt.logicalOR || this.type === tt.logicalAND
  1554. var op = this.value
  1555. this.next()
  1556. var startPos = this.start, startLoc = this.startLoc
  1557. var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn)
  1558. var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical)
  1559. return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
  1560. }
  1561. }
  1562. return left
  1563. }
  1564. pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
  1565. var node = this.startNodeAt(startPos, startLoc)
  1566. node.left = left
  1567. node.operator = op
  1568. node.right = right
  1569. return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
  1570. }
  1571. // Parse unary operators, both prefix and postfix.
  1572. pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
  1573. var this$1 = this;
  1574. var startPos = this.start, startLoc = this.startLoc, expr
  1575. if (this.inAsync && this.isContextual("await")) {
  1576. expr = this.parseAwait(refDestructuringErrors)
  1577. sawUnary = true
  1578. } else if (this.type.prefix) {
  1579. var node = this.startNode(), update = this.type === tt.incDec
  1580. node.operator = this.value
  1581. node.prefix = true
  1582. this.next()
  1583. node.argument = this.parseMaybeUnary(null, true)
  1584. this.checkExpressionErrors(refDestructuringErrors, true)
  1585. if (update) this.checkLVal(node.argument)
  1586. else if (this.strict && node.operator === "delete" &&
  1587. node.argument.type === "Identifier")
  1588. this.raiseRecoverable(node.start, "Deleting local variable in strict mode")
  1589. else sawUnary = true
  1590. expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression")
  1591. } else {
  1592. expr = this.parseExprSubscripts(refDestructuringErrors)
  1593. if (this.checkExpressionErrors(refDestructuringErrors)) return expr
  1594. while (this.type.postfix && !this.canInsertSemicolon()) {
  1595. var node$1 = this$1.startNodeAt(startPos, startLoc)
  1596. node$1.operator = this$1.value
  1597. node$1.prefix = false
  1598. node$1.argument = expr
  1599. this$1.checkLVal(expr)
  1600. this$1.next()
  1601. expr = this$1.finishNode(node$1, "UpdateExpression")
  1602. }
  1603. }
  1604. if (!sawUnary && this.eat(tt.starstar))
  1605. return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false)
  1606. else
  1607. return expr
  1608. }
  1609. // Parse call, dot, and `[]`-subscript expressions.
  1610. pp$3.parseExprSubscripts = function(refDestructuringErrors) {
  1611. var startPos = this.start, startLoc = this.startLoc
  1612. var expr = this.parseExprAtom(refDestructuringErrors)
  1613. var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")"
  1614. if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr
  1615. var result = this.parseSubscripts(expr, startPos, startLoc)
  1616. if (refDestructuringErrors && result.type === "MemberExpression") {
  1617. if (refDestructuringErrors.parenthesizedAssign >= result.start) refDestructuringErrors.parenthesizedAssign = -1
  1618. if (refDestructuringErrors.parenthesizedBind >= result.start) refDestructuringErrors.parenthesizedBind = -1
  1619. }
  1620. return result
  1621. }
  1622. pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {
  1623. var this$1 = this;
  1624. var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
  1625. this.lastTokEnd == base.end && !this.canInsertSemicolon()
  1626. for (var computed;;) {
  1627. if ((computed = this$1.eat(tt.bracketL)) || this$1.eat(tt.dot)) {
  1628. var node = this$1.startNodeAt(startPos, startLoc)
  1629. node.object = base
  1630. node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true)
  1631. node.computed = !!computed
  1632. if (computed) this$1.expect(tt.bracketR)
  1633. base = this$1.finishNode(node, "MemberExpression")
  1634. } else if (!noCalls && this$1.eat(tt.parenL)) {
  1635. var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos
  1636. this$1.yieldPos = 0
  1637. this$1.awaitPos = 0
  1638. var exprList = this$1.parseExprList(tt.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors)
  1639. if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(tt.arrow)) {
  1640. this$1.checkPatternErrors(refDestructuringErrors, false)
  1641. this$1.checkYieldAwaitInDefaultParams()
  1642. this$1.yieldPos = oldYieldPos
  1643. this$1.awaitPos = oldAwaitPos
  1644. return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true)
  1645. }
  1646. this$1.checkExpressionErrors(refDestructuringErrors, true)
  1647. this$1.yieldPos = oldYieldPos || this$1.yieldPos
  1648. this$1.awaitPos = oldAwaitPos || this$1.awaitPos
  1649. var node$1 = this$1.startNodeAt(startPos, startLoc)
  1650. node$1.callee = base
  1651. node$1.arguments = exprList
  1652. base = this$1.finishNode(node$1, "CallExpression")
  1653. } else if (this$1.type === tt.backQuote) {
  1654. var node$2 = this$1.startNodeAt(startPos, startLoc)
  1655. node$2.tag = base
  1656. node$2.quasi = this$1.parseTemplate()
  1657. base = this$1.finishNode(node$2, "TaggedTemplateExpression")
  1658. } else {
  1659. return base
  1660. }
  1661. }
  1662. }
  1663. // Parse an atomic expression — either a single token that is an
  1664. // expression, an expression started by a keyword like `function` or
  1665. // `new`, or an expression wrapped in punctuation like `()`, `[]`,
  1666. // or `{}`.
  1667. pp$3.parseExprAtom = function(refDestructuringErrors) {
  1668. var node, canBeArrow = this.potentialArrowAt == this.start
  1669. switch (this.type) {
  1670. case tt._super:
  1671. if (!this.inFunction)
  1672. this.raise(this.start, "'super' outside of function or class")
  1673. case tt._this:
  1674. var type = this.type === tt._this ? "ThisExpression" : "Super"
  1675. node = this.startNode()
  1676. this.next()
  1677. return this.finishNode(node, type)
  1678. case tt.name:
  1679. var startPos = this.start, startLoc = this.startLoc
  1680. var id = this.parseIdent(this.type !== tt.name)
  1681. if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function))
  1682. return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true)
  1683. if (canBeArrow && !this.canInsertSemicolon()) {
  1684. if (this.eat(tt.arrow))
  1685. return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false)
  1686. if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === tt.name) {
  1687. id = this.parseIdent()
  1688. if (this.canInsertSemicolon() || !this.eat(tt.arrow))
  1689. this.unexpected()
  1690. return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
  1691. }
  1692. }
  1693. return id
  1694. case tt.regexp:
  1695. var value = this.value
  1696. node = this.parseLiteral(value.value)
  1697. node.regex = {pattern: value.pattern, flags: value.flags}
  1698. return node
  1699. case tt.num: case tt.string:
  1700. return this.parseLiteral(this.value)
  1701. case tt._null: case tt._true: case tt._false:
  1702. node = this.startNode()
  1703. node.value = this.type === tt._null ? null : this.type === tt._true
  1704. node.raw = this.type.keyword
  1705. this.next()
  1706. return this.finishNode(node, "Literal")
  1707. case tt.parenL:
  1708. var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow)
  1709. if (refDestructuringErrors) {
  1710. if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
  1711. refDestructuringErrors.parenthesizedAssign = start
  1712. if (refDestructuringErrors.parenthesizedBind < 0)
  1713. refDestructuringErrors.parenthesizedBind = start
  1714. }
  1715. return expr
  1716. case tt.bracketL:
  1717. node = this.startNode()
  1718. this.next()
  1719. node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors)
  1720. return this.finishNode(node, "ArrayExpression")
  1721. case tt.braceL:
  1722. return this.parseObj(false, refDestructuringErrors)
  1723. case tt._function:
  1724. node = this.startNode()
  1725. this.next()
  1726. return this.parseFunction(node, false)
  1727. case tt._class:
  1728. return this.parseClass(this.startNode(), false)
  1729. case tt._new:
  1730. return this.parseNew()
  1731. case tt.backQuote:
  1732. return this.parseTemplate()
  1733. default:
  1734. this.unexpected()
  1735. }
  1736. }
  1737. pp$3.parseLiteral = function(value) {
  1738. var node = this.startNode()
  1739. node.value = value
  1740. node.raw = this.input.slice(this.start, this.end)
  1741. this.next()
  1742. return this.finishNode(node, "Literal")
  1743. }
  1744. pp$3.parseParenExpression = function() {
  1745. this.expect(tt.parenL)
  1746. var val = this.parseExpression()
  1747. this.expect(tt.parenR)
  1748. return val
  1749. }
  1750. pp$3.parseParenAndDistinguishExpression = function(canBeArrow) {
  1751. var this$1 = this;
  1752. var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8
  1753. if (this.options.ecmaVersion >= 6) {
  1754. this.next()
  1755. var innerStartPos = this.start, innerStartLoc = this.startLoc
  1756. var exprList = [], first = true, lastIsComma = false
  1757. var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart
  1758. this.yieldPos = 0
  1759. this.awaitPos = 0
  1760. while (this.type !== tt.parenR) {
  1761. first ? first = false : this$1.expect(tt.comma)
  1762. if (allowTrailingComma && this$1.afterTrailingComma(tt.parenR, true)) {
  1763. lastIsComma = true
  1764. break
  1765. } else if (this$1.type === tt.ellipsis) {
  1766. spreadStart = this$1.start
  1767. exprList.push(this$1.parseParenItem(this$1.parseRest()))
  1768. if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element")
  1769. break
  1770. } else {
  1771. if (this$1.type === tt.parenL && !innerParenStart) {
  1772. innerParenStart = this$1.start
  1773. }
  1774. exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem))
  1775. }
  1776. }
  1777. var innerEndPos = this.start, innerEndLoc = this.startLoc
  1778. this.expect(tt.parenR)
  1779. if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
  1780. this.checkPatternErrors(refDestructuringErrors, false)
  1781. this.checkYieldAwaitInDefaultParams()
  1782. if (innerParenStart) this.unexpected(innerParenStart)
  1783. this.yieldPos = oldYieldPos
  1784. this.awaitPos = oldAwaitPos
  1785. return this.parseParenArrowList(startPos, startLoc, exprList)
  1786. }
  1787. if (!exprList.length || lastIsComma) this.unexpected(this.lastTokStart)
  1788. if (spreadStart) this.unexpected(spreadStart)
  1789. this.checkExpressionErrors(refDestructuringErrors, true)
  1790. this.yieldPos = oldYieldPos || this.yieldPos
  1791. this.awaitPos = oldAwaitPos || this.awaitPos
  1792. if (exprList.length > 1) {
  1793. val = this.startNodeAt(innerStartPos, innerStartLoc)
  1794. val.expressions = exprList
  1795. this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc)
  1796. } else {
  1797. val = exprList[0]
  1798. }
  1799. } else {
  1800. val = this.parseParenExpression()
  1801. }
  1802. if (this.options.preserveParens) {
  1803. var par = this.startNodeAt(startPos, startLoc)
  1804. par.expression = val
  1805. return this.finishNode(par, "ParenthesizedExpression")
  1806. } else {
  1807. return val
  1808. }
  1809. }
  1810. pp$3.parseParenItem = function(item) {
  1811. return item
  1812. }
  1813. pp$3.parseParenArrowList = function(startPos, startLoc, exprList) {
  1814. return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
  1815. }
  1816. // New's precedence is slightly tricky. It must allow its argument to
  1817. // be a `[]` or dot subscript expression, but not a call — at least,
  1818. // not without wrapping it in parentheses. Thus, it uses the noCalls
  1819. // argument to parseSubscripts to prevent it from consuming the
  1820. // argument list.
  1821. var empty$1 = []
  1822. pp$3.parseNew = function() {
  1823. var node = this.startNode()
  1824. var meta = this.parseIdent(true)
  1825. if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) {
  1826. node.meta = meta
  1827. node.property = this.parseIdent(true)
  1828. if (node.property.name !== "target")
  1829. this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target")
  1830. if (!this.inFunction)
  1831. this.raiseRecoverable(node.start, "new.target can only be used in functions")
  1832. return this.finishNode(node, "MetaProperty")
  1833. }
  1834. var startPos = this.start, startLoc = this.startLoc
  1835. node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true)
  1836. if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false)
  1837. else node.arguments = empty$1
  1838. return this.finishNode(node, "NewExpression")
  1839. }
  1840. // Parse template expression.
  1841. pp$3.parseTemplateElement = function() {
  1842. var elem = this.startNode()
  1843. elem.value = {
  1844. raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'),
  1845. cooked: this.value
  1846. }
  1847. this.next()
  1848. elem.tail = this.type === tt.backQuote
  1849. return this.finishNode(elem, "TemplateElement")
  1850. }
  1851. pp$3.parseTemplate = function() {
  1852. var this$1 = this;
  1853. var node = this.startNode()
  1854. this.next()
  1855. node.expressions = []
  1856. var curElt = this.parseTemplateElement()
  1857. node.quasis = [curElt]
  1858. while (!curElt.tail) {
  1859. this$1.expect(tt.dollarBraceL)
  1860. node.expressions.push(this$1.parseExpression())
  1861. this$1.expect(tt.braceR)
  1862. node.quasis.push(curElt = this$1.parseTemplateElement())
  1863. }
  1864. this.next()
  1865. return this.finishNode(node, "TemplateLiteral")
  1866. }
  1867. // Parse an object literal or binding pattern.
  1868. pp$3.parseObj = function(isPattern, refDestructuringErrors) {
  1869. var this$1 = this;
  1870. var node = this.startNode(), first = true, propHash = {}
  1871. node.properties = []
  1872. this.next()
  1873. while (!this.eat(tt.braceR)) {
  1874. if (!first) {
  1875. this$1.expect(tt.comma)
  1876. if (this$1.afterTrailingComma(tt.braceR)) break
  1877. } else first = false
  1878. var prop = this$1.startNode(), isGenerator, isAsync, startPos, startLoc
  1879. if (this$1.options.ecmaVersion >= 6) {
  1880. prop.method = false
  1881. prop.shorthand = false
  1882. if (isPattern || refDestructuringErrors) {
  1883. startPos = this$1.start
  1884. startLoc = this$1.startLoc
  1885. }
  1886. if (!isPattern)
  1887. isGenerator = this$1.eat(tt.star)
  1888. }
  1889. this$1.parsePropertyName(prop)
  1890. if (!isPattern && this$1.options.ecmaVersion >= 8 && !isGenerator && !prop.computed &&
  1891. prop.key.type === "Identifier" && prop.key.name === "async" && this$1.type !== tt.parenL &&
  1892. this$1.type !== tt.colon && !this$1.canInsertSemicolon()) {
  1893. isAsync = true
  1894. this$1.parsePropertyName(prop, refDestructuringErrors)
  1895. } else {
  1896. isAsync = false
  1897. }
  1898. this$1.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors)
  1899. this$1.checkPropClash(prop, propHash)
  1900. node.properties.push(this$1.finishNode(prop, "Property"))
  1901. }
  1902. return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
  1903. }
  1904. pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) {
  1905. if ((isGenerator || isAsync) && this.type === tt.colon)
  1906. this.unexpected()
  1907. if (this.eat(tt.colon)) {
  1908. prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors)
  1909. prop.kind = "init"
  1910. } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) {
  1911. if (isPattern) this.unexpected()
  1912. prop.kind = "init"
  1913. prop.method = true
  1914. prop.value = this.parseMethod(isGenerator, isAsync)
  1915. } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
  1916. (prop.key.name === "get" || prop.key.name === "set") &&
  1917. (this.type != tt.comma && this.type != tt.braceR)) {
  1918. if (isGenerator || isAsync || isPattern) this.unexpected()
  1919. prop.kind = prop.key.name
  1920. this.parsePropertyName(prop)
  1921. prop.value = this.parseMethod(false)
  1922. var paramCount = prop.kind === "get" ? 0 : 1
  1923. if (prop.value.params.length !== paramCount) {
  1924. var start = prop.value.start
  1925. if (prop.kind === "get")
  1926. this.raiseRecoverable(start, "getter should have no params")
  1927. else
  1928. this.raiseRecoverable(start, "setter should have exactly one param")
  1929. } else {
  1930. if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
  1931. this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params")
  1932. }
  1933. } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
  1934. if (this.keywords.test(prop.key.name) ||
  1935. (this.strict ? this.reservedWordsStrict : this.reservedWords).test(prop.key.name) ||
  1936. (this.inGenerator && prop.key.name == "yield") ||
  1937. (this.inAsync && prop.key.name == "await"))
  1938. this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property")
  1939. prop.kind = "init"
  1940. if (isPattern) {
  1941. prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key)
  1942. } else if (this.type === tt.eq && refDestructuringErrors) {
  1943. if (refDestructuringErrors.shorthandAssign < 0)
  1944. refDestructuringErrors.shorthandAssign = this.start
  1945. prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key)
  1946. } else {
  1947. prop.value = prop.key
  1948. }
  1949. prop.shorthand = true
  1950. } else this.unexpected()
  1951. }
  1952. pp$3.parsePropertyName = function(prop) {
  1953. if (this.options.ecmaVersion >= 6) {
  1954. if (this.eat(tt.bracketL)) {
  1955. prop.computed = true
  1956. prop.key = this.parseMaybeAssign()
  1957. this.expect(tt.bracketR)
  1958. return prop.key
  1959. } else {
  1960. prop.computed = false
  1961. }
  1962. }
  1963. return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true)
  1964. }
  1965. // Initialize empty function node.
  1966. pp$3.initFunction = function(node) {
  1967. node.id = null
  1968. if (this.options.ecmaVersion >= 6) {
  1969. node.generator = false
  1970. node.expression = false
  1971. }
  1972. if (this.options.ecmaVersion >= 8)
  1973. node.async = false
  1974. }
  1975. // Parse object or class method.
  1976. pp$3.parseMethod = function(isGenerator, isAsync) {
  1977. var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync,
  1978. oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction
  1979. this.initFunction(node)
  1980. if (this.options.ecmaVersion >= 6)
  1981. node.generator = isGenerator
  1982. if (this.options.ecmaVersion >= 8)
  1983. node.async = !!isAsync
  1984. this.inGenerator = node.generator
  1985. this.inAsync = node.async
  1986. this.yieldPos = 0
  1987. this.awaitPos = 0
  1988. this.inFunction = true
  1989. this.expect(tt.parenL)
  1990. node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8)
  1991. this.checkYieldAwaitInDefaultParams()
  1992. this.parseFunctionBody(node, false)
  1993. this.inGenerator = oldInGen
  1994. this.inAsync = oldInAsync
  1995. this.yieldPos = oldYieldPos
  1996. this.awaitPos = oldAwaitPos
  1997. this.inFunction = oldInFunc
  1998. return this.finishNode(node, "FunctionExpression")
  1999. }
  2000. // Parse arrow function expression with given parameters.
  2001. pp$3.parseArrowExpression = function(node, params, isAsync) {
  2002. var oldInGen = this.inGenerator, oldInAsync = this.inAsync,
  2003. oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction
  2004. this.initFunction(node)
  2005. if (this.options.ecmaVersion >= 8)
  2006. node.async = !!isAsync
  2007. this.inGenerator = false
  2008. this.inAsync = node.async
  2009. this.yieldPos = 0
  2010. this.awaitPos = 0
  2011. this.inFunction = true
  2012. node.params = this.toAssignableList(params, true)
  2013. this.parseFunctionBody(node, true)
  2014. this.inGenerator = oldInGen
  2015. this.inAsync = oldInAsync
  2016. this.yieldPos = oldYieldPos
  2017. this.awaitPos = oldAwaitPos
  2018. this.inFunction = oldInFunc
  2019. return this.finishNode(node, "ArrowFunctionExpression")
  2020. }
  2021. // Parse function body and check parameters.
  2022. pp$3.parseFunctionBody = function(node, isArrowFunction) {
  2023. var isExpression = isArrowFunction && this.type !== tt.braceL
  2024. var oldStrict = this.strict, useStrict = false
  2025. if (isExpression) {
  2026. node.body = this.parseMaybeAssign()
  2027. node.expression = true
  2028. } else {
  2029. var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params)
  2030. if (!oldStrict || nonSimple) {
  2031. useStrict = this.strictDirective(this.end)
  2032. // If this is a strict mode function, verify that argument names
  2033. // are not repeated, and it does not try to bind the words `eval`
  2034. // or `arguments`.
  2035. if (useStrict && nonSimple)
  2036. this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list")
  2037. }
  2038. // Start a new scope with regard to labels and the `inFunction`
  2039. // flag (restore them to their old value afterwards).
  2040. var oldLabels = this.labels
  2041. this.labels = []
  2042. if (useStrict) this.strict = true
  2043. node.body = this.parseBlock(true)
  2044. node.expression = false
  2045. this.labels = oldLabels
  2046. }
  2047. if (oldStrict || useStrict) {
  2048. this.strict = true
  2049. if (node.id)
  2050. this.checkLVal(node.id, true)
  2051. this.checkParams(node)
  2052. this.strict = oldStrict
  2053. } else if (isArrowFunction || !this.isSimpleParamList(node.params)) {
  2054. this.checkParams(node)
  2055. }
  2056. }
  2057. pp$3.isSimpleParamList = function(params) {
  2058. for (var i = 0; i < params.length; i++)
  2059. if (params[i].type !== "Identifier") return false
  2060. return true
  2061. }
  2062. // Checks function params for various disallowed patterns such as using "eval"
  2063. // or "arguments" and duplicate parameters.
  2064. pp$3.checkParams = function(node) {
  2065. var this$1 = this;
  2066. var nameHash = {}
  2067. for (var i = 0; i < node.params.length; i++) this$1.checkLVal(node.params[i], true, nameHash)
  2068. }
  2069. // Parses a comma-separated list of expressions, and returns them as
  2070. // an array. `close` is the token type that ends the list, and
  2071. // `allowEmpty` can be turned on to allow subsequent commas with
  2072. // nothing in between them to be parsed as `null` (which is needed
  2073. // for array literals).
  2074. pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
  2075. var this$1 = this;
  2076. var elts = [], first = true
  2077. while (!this.eat(close)) {
  2078. if (!first) {
  2079. this$1.expect(tt.comma)
  2080. if (allowTrailingComma && this$1.afterTrailingComma(close)) break
  2081. } else first = false
  2082. var elt
  2083. if (allowEmpty && this$1.type === tt.comma)
  2084. elt = null
  2085. else if (this$1.type === tt.ellipsis) {
  2086. elt = this$1.parseSpread(refDestructuringErrors)
  2087. if (refDestructuringErrors && this$1.type === tt.comma && refDestructuringErrors.trailingComma < 0)
  2088. refDestructuringErrors.trailingComma = this$1.start
  2089. } else {
  2090. elt = this$1.parseMaybeAssign(false, refDestructuringErrors)
  2091. }
  2092. elts.push(elt)
  2093. }
  2094. return elts
  2095. }
  2096. // Parse the next token as an identifier. If `liberal` is true (used
  2097. // when parsing properties), it will also convert keywords into
  2098. // identifiers.
  2099. pp$3.parseIdent = function(liberal) {
  2100. var node = this.startNode()
  2101. if (liberal && this.options.allowReserved == "never") liberal = false
  2102. if (this.type === tt.name) {
  2103. if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) &&
  2104. (this.options.ecmaVersion >= 6 ||
  2105. this.input.slice(this.start, this.end).indexOf("\\") == -1))
  2106. this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved")
  2107. if (this.inGenerator && this.value === "yield")
  2108. this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator")
  2109. if (this.inAsync && this.value === "await")
  2110. this.raiseRecoverable(this.start, "Can not use 'await' as identifier inside an async function")
  2111. node.name = this.value
  2112. } else if (liberal && this.type.keyword) {
  2113. node.name = this.type.keyword
  2114. } else {
  2115. this.unexpected()
  2116. }
  2117. this.next()
  2118. return this.finishNode(node, "Identifier")
  2119. }
  2120. // Parses yield expression inside generator.
  2121. pp$3.parseYield = function() {
  2122. if (!this.yieldPos) this.yieldPos = this.start
  2123. var node = this.startNode()
  2124. this.next()
  2125. if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) {
  2126. node.delegate = false
  2127. node.argument = null
  2128. } else {
  2129. node.delegate = this.eat(tt.star)
  2130. node.argument = this.parseMaybeAssign()
  2131. }
  2132. return this.finishNode(node, "YieldExpression")
  2133. }
  2134. pp$3.parseAwait = function() {
  2135. if (!this.awaitPos) this.awaitPos = this.start
  2136. var node = this.startNode()
  2137. this.next()
  2138. node.argument = this.parseMaybeUnary(null, true)
  2139. return this.finishNode(node, "AwaitExpression")
  2140. }
  2141. var pp$4 = Parser.prototype
  2142. // This function is used to raise exceptions on parse errors. It
  2143. // takes an offset integer (into the current `input`) to indicate
  2144. // the location of the error, attaches the position to the end
  2145. // of the error message, and then raises a `SyntaxError` with that
  2146. // message.
  2147. pp$4.raise = function(pos, message) {
  2148. var loc = getLineInfo(this.input, pos)
  2149. message += " (" + loc.line + ":" + loc.column + ")"
  2150. var err = new SyntaxError(message)
  2151. err.pos = pos; err.loc = loc; err.raisedAt = this.pos
  2152. throw err
  2153. }
  2154. pp$4.raiseRecoverable = pp$4.raise
  2155. pp$4.curPosition = function() {
  2156. if (this.options.locations) {
  2157. return new Position(this.curLine, this.pos - this.lineStart)
  2158. }
  2159. }
  2160. var Node = function Node(parser, pos, loc) {
  2161. this.type = ""
  2162. this.start = pos
  2163. this.end = 0
  2164. if (parser.options.locations)
  2165. this.loc = new SourceLocation(parser, loc)
  2166. if (parser.options.directSourceFile)
  2167. this.sourceFile = parser.options.directSourceFile
  2168. if (parser.options.ranges)
  2169. this.range = [pos, 0]
  2170. };
  2171. // Start an AST node, attaching a start offset.
  2172. var pp$5 = Parser.prototype
  2173. pp$5.startNode = function() {
  2174. return new Node(this, this.start, this.startLoc)
  2175. }
  2176. pp$5.startNodeAt = function(pos, loc) {
  2177. return new Node(this, pos, loc)
  2178. }
  2179. // Finish an AST node, adding `type` and `end` properties.
  2180. function finishNodeAt(node, type, pos, loc) {
  2181. node.type = type
  2182. node.end = pos
  2183. if (this.options.locations)
  2184. node.loc.end = loc
  2185. if (this.options.ranges)
  2186. node.range[1] = pos
  2187. return node
  2188. }
  2189. pp$5.finishNode = function(node, type) {
  2190. return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
  2191. }
  2192. // Finish node at given position
  2193. pp$5.finishNodeAt = function(node, type, pos, loc) {
  2194. return finishNodeAt.call(this, node, type, pos, loc)
  2195. }
  2196. // The algorithm used to determine whether a regexp can appear at a
  2197. // given point in the program is loosely based on sweet.js' approach.
  2198. // See https://github.com/mozilla/sweet.js/wiki/design
  2199. var TokContext = function TokContext(token, isExpr, preserveSpace, override) {
  2200. this.token = token
  2201. this.isExpr = !!isExpr
  2202. this.preserveSpace = !!preserveSpace
  2203. this.override = override
  2204. };
  2205. var types = {
  2206. b_stat: new TokContext("{", false),
  2207. b_expr: new TokContext("{", true),
  2208. b_tmpl: new TokContext("${", true),
  2209. p_stat: new TokContext("(", false),
  2210. p_expr: new TokContext("(", true),
  2211. q_tmpl: new TokContext("`", true, true, function (p) { return p.readTmplToken(); }),
  2212. f_expr: new TokContext("function", true)
  2213. }
  2214. var pp$6 = Parser.prototype
  2215. pp$6.initialContext = function() {
  2216. return [types.b_stat]
  2217. }
  2218. pp$6.braceIsBlock = function(prevType) {
  2219. if (prevType === tt.colon) {
  2220. var parent = this.curContext()
  2221. if (parent === types.b_stat || parent === types.b_expr)
  2222. return !parent.isExpr
  2223. }
  2224. if (prevType === tt._return)
  2225. return lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
  2226. if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR)
  2227. return true
  2228. if (prevType == tt.braceL)
  2229. return this.curContext() === types.b_stat
  2230. return !this.exprAllowed
  2231. }
  2232. pp$6.updateContext = function(prevType) {
  2233. var update, type = this.type
  2234. if (type.keyword && prevType == tt.dot)
  2235. this.exprAllowed = false
  2236. else if (update = type.updateContext)
  2237. update.call(this, prevType)
  2238. else
  2239. this.exprAllowed = type.beforeExpr
  2240. }
  2241. // Token-specific context update code
  2242. tt.parenR.updateContext = tt.braceR.updateContext = function() {
  2243. if (this.context.length == 1) {
  2244. this.exprAllowed = true
  2245. return
  2246. }
  2247. var out = this.context.pop()
  2248. if (out === types.b_stat && this.curContext() === types.f_expr) {
  2249. this.context.pop()
  2250. this.exprAllowed = false
  2251. } else if (out === types.b_tmpl) {
  2252. this.exprAllowed = true
  2253. } else {
  2254. this.exprAllowed = !out.isExpr
  2255. }
  2256. }
  2257. tt.braceL.updateContext = function(prevType) {
  2258. this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr)
  2259. this.exprAllowed = true
  2260. }
  2261. tt.dollarBraceL.updateContext = function() {
  2262. this.context.push(types.b_tmpl)
  2263. this.exprAllowed = true
  2264. }
  2265. tt.parenL.updateContext = function(prevType) {
  2266. var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while
  2267. this.context.push(statementParens ? types.p_stat : types.p_expr)
  2268. this.exprAllowed = true
  2269. }
  2270. tt.incDec.updateContext = function() {
  2271. // tokExprAllowed stays unchanged
  2272. }
  2273. tt._function.updateContext = function(prevType) {
  2274. if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else &&
  2275. !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat))
  2276. this.context.push(types.f_expr)
  2277. this.exprAllowed = false
  2278. }
  2279. tt.backQuote.updateContext = function() {
  2280. if (this.curContext() === types.q_tmpl)
  2281. this.context.pop()
  2282. else
  2283. this.context.push(types.q_tmpl)
  2284. this.exprAllowed = false
  2285. }
  2286. // Object type used to represent tokens. Note that normally, tokens
  2287. // simply exist as properties on the parser object. This is only
  2288. // used for the onToken callback and the external tokenizer.
  2289. var Token = function Token(p) {
  2290. this.type = p.type
  2291. this.value = p.value
  2292. this.start = p.start
  2293. this.end = p.end
  2294. if (p.options.locations)
  2295. this.loc = new SourceLocation(p, p.startLoc, p.endLoc)
  2296. if (p.options.ranges)
  2297. this.range = [p.start, p.end]
  2298. };
  2299. // ## Tokenizer
  2300. var pp$7 = Parser.prototype
  2301. // Are we running under Rhino?
  2302. var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]"
  2303. // Move to the next token
  2304. pp$7.next = function() {
  2305. if (this.options.onToken)
  2306. this.options.onToken(new Token(this))
  2307. this.lastTokEnd = this.end
  2308. this.lastTokStart = this.start
  2309. this.lastTokEndLoc = this.endLoc
  2310. this.lastTokStartLoc = this.startLoc
  2311. this.nextToken()
  2312. }
  2313. pp$7.getToken = function() {
  2314. this.next()
  2315. return new Token(this)
  2316. }
  2317. // If we're in an ES6 environment, make parsers iterable
  2318. if (typeof Symbol !== "undefined")
  2319. pp$7[Symbol.iterator] = function () {
  2320. var self = this
  2321. return {next: function () {
  2322. var token = self.getToken()
  2323. return {
  2324. done: token.type === tt.eof,
  2325. value: token
  2326. }
  2327. }}
  2328. }
  2329. // Toggle strict mode. Re-reads the next number or string to please
  2330. // pedantic tests (`"use strict"; 010;` should fail).
  2331. pp$7.curContext = function() {
  2332. return this.context[this.context.length - 1]
  2333. }
  2334. // Read a single token, updating the parser object's token-related
  2335. // properties.
  2336. pp$7.nextToken = function() {
  2337. var curContext = this.curContext()
  2338. if (!curContext || !curContext.preserveSpace) this.skipSpace()
  2339. this.start = this.pos
  2340. if (this.options.locations) this.startLoc = this.curPosition()
  2341. if (this.pos >= this.input.length) return this.finishToken(tt.eof)
  2342. if (curContext.override) return curContext.override(this)
  2343. else this.readToken(this.fullCharCodeAtPos())
  2344. }
  2345. pp$7.readToken = function(code) {
  2346. // Identifier or keyword. '\uXXXX' sequences are allowed in
  2347. // identifiers, so '\' also dispatches to that.
  2348. if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
  2349. return this.readWord()
  2350. return this.getTokenFromCode(code)
  2351. }
  2352. pp$7.fullCharCodeAtPos = function() {
  2353. var code = this.input.charCodeAt(this.pos)
  2354. if (code <= 0xd7ff || code >= 0xe000) return code
  2355. var next = this.input.charCodeAt(this.pos + 1)
  2356. return (code << 10) + next - 0x35fdc00
  2357. }
  2358. pp$7.skipBlockComment = function() {
  2359. var this$1 = this;
  2360. var startLoc = this.options.onComment && this.curPosition()
  2361. var start = this.pos, end = this.input.indexOf("*/", this.pos += 2)
  2362. if (end === -1) this.raise(this.pos - 2, "Unterminated comment")
  2363. this.pos = end + 2
  2364. if (this.options.locations) {
  2365. lineBreakG.lastIndex = start
  2366. var match
  2367. while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
  2368. ++this$1.curLine
  2369. this$1.lineStart = match.index + match[0].length
  2370. }
  2371. }
  2372. if (this.options.onComment)
  2373. this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
  2374. startLoc, this.curPosition())
  2375. }
  2376. pp$7.skipLineComment = function(startSkip) {
  2377. var this$1 = this;
  2378. var start = this.pos
  2379. var startLoc = this.options.onComment && this.curPosition()
  2380. var ch = this.input.charCodeAt(this.pos+=startSkip)
  2381. while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
  2382. ++this$1.pos
  2383. ch = this$1.input.charCodeAt(this$1.pos)
  2384. }
  2385. if (this.options.onComment)
  2386. this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
  2387. startLoc, this.curPosition())
  2388. }
  2389. // Called at the start of the parse and after every token. Skips
  2390. // whitespace and comments, and.
  2391. pp$7.skipSpace = function() {
  2392. var this$1 = this;
  2393. loop: while (this.pos < this.input.length) {
  2394. var ch = this$1.input.charCodeAt(this$1.pos)
  2395. switch (ch) {
  2396. case 32: case 160: // ' '
  2397. ++this$1.pos
  2398. break
  2399. case 13:
  2400. if (this$1.input.charCodeAt(this$1.pos + 1) === 10) {
  2401. ++this$1.pos
  2402. }
  2403. case 10: case 8232: case 8233:
  2404. ++this$1.pos
  2405. if (this$1.options.locations) {
  2406. ++this$1.curLine
  2407. this$1.lineStart = this$1.pos
  2408. }
  2409. break
  2410. case 47: // '/'
  2411. switch (this$1.input.charCodeAt(this$1.pos + 1)) {
  2412. case 42: // '*'
  2413. this$1.skipBlockComment()
  2414. break
  2415. case 47:
  2416. this$1.skipLineComment(2)
  2417. break
  2418. default:
  2419. break loop
  2420. }
  2421. break
  2422. default:
  2423. if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
  2424. ++this$1.pos
  2425. } else {
  2426. break loop
  2427. }
  2428. }
  2429. }
  2430. }
  2431. // Called at the end of every token. Sets `end`, `val`, and
  2432. // maintains `context` and `exprAllowed`, and skips the space after
  2433. // the token, so that the next one's `start` will point at the
  2434. // right position.
  2435. pp$7.finishToken = function(type, val) {
  2436. this.end = this.pos
  2437. if (this.options.locations) this.endLoc = this.curPosition()
  2438. var prevType = this.type
  2439. this.type = type
  2440. this.value = val
  2441. this.updateContext(prevType)
  2442. }
  2443. // ### Token reading
  2444. // This is the function that is called to fetch the next token. It
  2445. // is somewhat obscure, because it works in character codes rather
  2446. // than characters, and because operator parsing has been inlined
  2447. // into it.
  2448. //
  2449. // All in the name of speed.
  2450. //
  2451. pp$7.readToken_dot = function() {
  2452. var next = this.input.charCodeAt(this.pos + 1)
  2453. if (next >= 48 && next <= 57) return this.readNumber(true)
  2454. var next2 = this.input.charCodeAt(this.pos + 2)
  2455. if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
  2456. this.pos += 3
  2457. return this.finishToken(tt.ellipsis)
  2458. } else {
  2459. ++this.pos
  2460. return this.finishToken(tt.dot)
  2461. }
  2462. }
  2463. pp$7.readToken_slash = function() { // '/'
  2464. var next = this.input.charCodeAt(this.pos + 1)
  2465. if (this.exprAllowed) {++this.pos; return this.readRegexp()}
  2466. if (next === 61) return this.finishOp(tt.assign, 2)
  2467. return this.finishOp(tt.slash, 1)
  2468. }
  2469. pp$7.readToken_mult_modulo_exp = function(code) { // '%*'
  2470. var next = this.input.charCodeAt(this.pos + 1)
  2471. var size = 1
  2472. var tokentype = code === 42 ? tt.star : tt.modulo
  2473. // exponentiation operator ** and **=
  2474. if (this.options.ecmaVersion >= 7 && next === 42) {
  2475. ++size
  2476. tokentype = tt.starstar
  2477. next = this.input.charCodeAt(this.pos + 2)
  2478. }
  2479. if (next === 61) return this.finishOp(tt.assign, size + 1)
  2480. return this.finishOp(tokentype, size)
  2481. }
  2482. pp$7.readToken_pipe_amp = function(code) { // '|&'
  2483. var next = this.input.charCodeAt(this.pos + 1)
  2484. if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2)
  2485. if (next === 61) return this.finishOp(tt.assign, 2)
  2486. return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1)
  2487. }
  2488. pp$7.readToken_caret = function() { // '^'
  2489. var next = this.input.charCodeAt(this.pos + 1)
  2490. if (next === 61) return this.finishOp(tt.assign, 2)
  2491. return this.finishOp(tt.bitwiseXOR, 1)
  2492. }
  2493. pp$7.readToken_plus_min = function(code) { // '+-'
  2494. var next = this.input.charCodeAt(this.pos + 1)
  2495. if (next === code) {
  2496. if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 &&
  2497. lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) {
  2498. // A `-->` line comment
  2499. this.skipLineComment(3)
  2500. this.skipSpace()
  2501. return this.nextToken()
  2502. }
  2503. return this.finishOp(tt.incDec, 2)
  2504. }
  2505. if (next === 61) return this.finishOp(tt.assign, 2)
  2506. return this.finishOp(tt.plusMin, 1)
  2507. }
  2508. pp$7.readToken_lt_gt = function(code) { // '<>'
  2509. var next = this.input.charCodeAt(this.pos + 1)
  2510. var size = 1
  2511. if (next === code) {
  2512. size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2
  2513. if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1)
  2514. return this.finishOp(tt.bitShift, size)
  2515. }
  2516. if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 &&
  2517. this.input.charCodeAt(this.pos + 3) == 45) {
  2518. if (this.inModule) this.unexpected()
  2519. // `<!--`, an XML-style comment that should be interpreted as a line comment
  2520. this.skipLineComment(4)
  2521. this.skipSpace()
  2522. return this.nextToken()
  2523. }
  2524. if (next === 61) size = 2
  2525. return this.finishOp(tt.relational, size)
  2526. }
  2527. pp$7.readToken_eq_excl = function(code) { // '=!'
  2528. var next = this.input.charCodeAt(this.pos + 1)
  2529. if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2)
  2530. if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
  2531. this.pos += 2
  2532. return this.finishToken(tt.arrow)
  2533. }
  2534. return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1)
  2535. }
  2536. pp$7.getTokenFromCode = function(code) {
  2537. switch (code) {
  2538. // The interpretation of a dot depends on whether it is followed
  2539. // by a digit or another two dots.
  2540. case 46: // '.'
  2541. return this.readToken_dot()
  2542. // Punctuation tokens.
  2543. case 40: ++this.pos; return this.finishToken(tt.parenL)
  2544. case 41: ++this.pos; return this.finishToken(tt.parenR)
  2545. case 59: ++this.pos; return this.finishToken(tt.semi)
  2546. case 44: ++this.pos; return this.finishToken(tt.comma)
  2547. case 91: ++this.pos; return this.finishToken(tt.bracketL)
  2548. case 93: ++this.pos; return this.finishToken(tt.bracketR)
  2549. case 123: ++this.pos; return this.finishToken(tt.braceL)
  2550. case 125: ++this.pos; return this.finishToken(tt.braceR)
  2551. case 58: ++this.pos; return this.finishToken(tt.colon)
  2552. case 63: ++this.pos; return this.finishToken(tt.question)
  2553. case 96: // '`'
  2554. if (this.options.ecmaVersion < 6) break
  2555. ++this.pos
  2556. return this.finishToken(tt.backQuote)
  2557. case 48: // '0'
  2558. var next = this.input.charCodeAt(this.pos + 1)
  2559. if (next === 120 || next === 88) return this.readRadixNumber(16) // '0x', '0X' - hex number
  2560. if (this.options.ecmaVersion >= 6) {
  2561. if (next === 111 || next === 79) return this.readRadixNumber(8) // '0o', '0O' - octal number
  2562. if (next === 98 || next === 66) return this.readRadixNumber(2) // '0b', '0B' - binary number
  2563. }
  2564. // Anything else beginning with a digit is an integer, octal
  2565. // number, or float.
  2566. case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
  2567. return this.readNumber(false)
  2568. // Quotes produce strings.
  2569. case 34: case 39: // '"', "'"
  2570. return this.readString(code)
  2571. // Operators are parsed inline in tiny state machines. '=' (61) is
  2572. // often referred to. `finishOp` simply skips the amount of
  2573. // characters it is given as second argument, and returns a token
  2574. // of the type given by its first argument.
  2575. case 47: // '/'
  2576. return this.readToken_slash()
  2577. case 37: case 42: // '%*'
  2578. return this.readToken_mult_modulo_exp(code)
  2579. case 124: case 38: // '|&'
  2580. return this.readToken_pipe_amp(code)
  2581. case 94: // '^'
  2582. return this.readToken_caret()
  2583. case 43: case 45: // '+-'
  2584. return this.readToken_plus_min(code)
  2585. case 60: case 62: // '<>'
  2586. return this.readToken_lt_gt(code)
  2587. case 61: case 33: // '=!'
  2588. return this.readToken_eq_excl(code)
  2589. case 126: // '~'
  2590. return this.finishOp(tt.prefix, 1)
  2591. }
  2592. this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'")
  2593. }
  2594. pp$7.finishOp = function(type, size) {
  2595. var str = this.input.slice(this.pos, this.pos + size)
  2596. this.pos += size
  2597. return this.finishToken(type, str)
  2598. }
  2599. // Parse a regular expression. Some context-awareness is necessary,
  2600. // since a '/' inside a '[]' set does not end the expression.
  2601. function tryCreateRegexp(src, flags, throwErrorAt, parser) {
  2602. try {
  2603. return new RegExp(src, flags)
  2604. } catch (e) {
  2605. if (throwErrorAt !== undefined) {
  2606. if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message)
  2607. throw e
  2608. }
  2609. }
  2610. }
  2611. var regexpUnicodeSupport = !!tryCreateRegexp("\uffff", "u")
  2612. pp$7.readRegexp = function() {
  2613. var this$1 = this;
  2614. var escaped, inClass, start = this.pos
  2615. for (;;) {
  2616. if (this$1.pos >= this$1.input.length) this$1.raise(start, "Unterminated regular expression")
  2617. var ch = this$1.input.charAt(this$1.pos)
  2618. if (lineBreak.test(ch)) this$1.raise(start, "Unterminated regular expression")
  2619. if (!escaped) {
  2620. if (ch === "[") inClass = true
  2621. else if (ch === "]" && inClass) inClass = false
  2622. else if (ch === "/" && !inClass) break
  2623. escaped = ch === "\\"
  2624. } else escaped = false
  2625. ++this$1.pos
  2626. }
  2627. var content = this.input.slice(start, this.pos)
  2628. ++this.pos
  2629. // Need to use `readWord1` because '\uXXXX' sequences are allowed
  2630. // here (don't ask).
  2631. var mods = this.readWord1()
  2632. var tmp = content, tmpFlags = ""
  2633. if (mods) {
  2634. var validFlags = /^[gim]*$/
  2635. if (this.options.ecmaVersion >= 6) validFlags = /^[gimuy]*$/
  2636. if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag")
  2637. if (mods.indexOf("u") >= 0) {
  2638. if (regexpUnicodeSupport) {
  2639. tmpFlags = "u"
  2640. } else {
  2641. // Replace each astral symbol and every Unicode escape sequence that
  2642. // possibly represents an astral symbol or a paired surrogate with a
  2643. // single ASCII symbol to avoid throwing on regular expressions that
  2644. // are only valid in combination with the `/u` flag.
  2645. // Note: replacing with the ASCII symbol `x` might cause false
  2646. // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
  2647. // perfectly valid pattern that is equivalent to `[a-b]`, but it would
  2648. // be replaced by `[x-b]` which throws an error.
  2649. tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (_match, code, offset) {
  2650. code = Number("0x" + code)
  2651. if (code > 0x10FFFF) this$1.raise(start + offset + 3, "Code point out of bounds")
  2652. return "x"
  2653. })
  2654. tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
  2655. tmpFlags = tmpFlags.replace("u", "")
  2656. }
  2657. }
  2658. }
  2659. // Detect invalid regular expressions.
  2660. var value = null
  2661. // Rhino's regular expression parser is flaky and throws uncatchable exceptions,
  2662. // so don't do detection if we are running under Rhino
  2663. if (!isRhino) {
  2664. tryCreateRegexp(tmp, tmpFlags, start, this)
  2665. // Get a regular expression object for this pattern-flag pair, or `null` in
  2666. // case the current environment doesn't support the flags it uses.
  2667. value = tryCreateRegexp(content, mods)
  2668. }
  2669. return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value})
  2670. }
  2671. // Read an integer in the given radix. Return null if zero digits
  2672. // were read, the integer value otherwise. When `len` is given, this
  2673. // will return `null` unless the integer has exactly `len` digits.
  2674. pp$7.readInt = function(radix, len) {
  2675. var this$1 = this;
  2676. var start = this.pos, total = 0
  2677. for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
  2678. var code = this$1.input.charCodeAt(this$1.pos), val
  2679. if (code >= 97) val = code - 97 + 10 // a
  2680. else if (code >= 65) val = code - 65 + 10 // A
  2681. else if (code >= 48 && code <= 57) val = code - 48 // 0-9
  2682. else val = Infinity
  2683. if (val >= radix) break
  2684. ++this$1.pos
  2685. total = total * radix + val
  2686. }
  2687. if (this.pos === start || len != null && this.pos - start !== len) return null
  2688. return total
  2689. }
  2690. pp$7.readRadixNumber = function(radix) {
  2691. this.pos += 2 // 0x
  2692. var val = this.readInt(radix)
  2693. if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix)
  2694. if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number")
  2695. return this.finishToken(tt.num, val)
  2696. }
  2697. // Read an integer, octal integer, or floating-point number.
  2698. pp$7.readNumber = function(startsWithDot) {
  2699. var start = this.pos, isFloat = false, octal = this.input.charCodeAt(this.pos) === 48
  2700. if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number")
  2701. if (octal && this.pos == start + 1) octal = false
  2702. var next = this.input.charCodeAt(this.pos)
  2703. if (next === 46 && !octal) { // '.'
  2704. ++this.pos
  2705. this.readInt(10)
  2706. isFloat = true
  2707. next = this.input.charCodeAt(this.pos)
  2708. }
  2709. if ((next === 69 || next === 101) && !octal) { // 'eE'
  2710. next = this.input.charCodeAt(++this.pos)
  2711. if (next === 43 || next === 45) ++this.pos // '+-'
  2712. if (this.readInt(10) === null) this.raise(start, "Invalid number")
  2713. isFloat = true
  2714. }
  2715. if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number")
  2716. var str = this.input.slice(start, this.pos), val
  2717. if (isFloat) val = parseFloat(str)
  2718. else if (!octal || str.length === 1) val = parseInt(str, 10)
  2719. else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number")
  2720. else val = parseInt(str, 8)
  2721. return this.finishToken(tt.num, val)
  2722. }
  2723. // Read a string value, interpreting backslash-escapes.
  2724. pp$7.readCodePoint = function() {
  2725. var ch = this.input.charCodeAt(this.pos), code
  2726. if (ch === 123) {
  2727. if (this.options.ecmaVersion < 6) this.unexpected()
  2728. var codePos = ++this.pos
  2729. code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos)
  2730. ++this.pos
  2731. if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds")
  2732. } else {
  2733. code = this.readHexChar(4)
  2734. }
  2735. return code
  2736. }
  2737. function codePointToString(code) {
  2738. // UTF-16 Decoding
  2739. if (code <= 0xFFFF) return String.fromCharCode(code)
  2740. code -= 0x10000
  2741. return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
  2742. }
  2743. pp$7.readString = function(quote) {
  2744. var this$1 = this;
  2745. var out = "", chunkStart = ++this.pos
  2746. for (;;) {
  2747. if (this$1.pos >= this$1.input.length) this$1.raise(this$1.start, "Unterminated string constant")
  2748. var ch = this$1.input.charCodeAt(this$1.pos)
  2749. if (ch === quote) break
  2750. if (ch === 92) { // '\'
  2751. out += this$1.input.slice(chunkStart, this$1.pos)
  2752. out += this$1.readEscapedChar(false)
  2753. chunkStart = this$1.pos
  2754. } else {
  2755. if (isNewLine(ch)) this$1.raise(this$1.start, "Unterminated string constant")
  2756. ++this$1.pos
  2757. }
  2758. }
  2759. out += this.input.slice(chunkStart, this.pos++)
  2760. return this.finishToken(tt.string, out)
  2761. }
  2762. // Reads template string tokens.
  2763. pp$7.readTmplToken = function() {
  2764. var this$1 = this;
  2765. var out = "", chunkStart = this.pos
  2766. for (;;) {
  2767. if (this$1.pos >= this$1.input.length) this$1.raise(this$1.start, "Unterminated template")
  2768. var ch = this$1.input.charCodeAt(this$1.pos)
  2769. if (ch === 96 || ch === 36 && this$1.input.charCodeAt(this$1.pos + 1) === 123) { // '`', '${'
  2770. if (this$1.pos === this$1.start && this$1.type === tt.template) {
  2771. if (ch === 36) {
  2772. this$1.pos += 2
  2773. return this$1.finishToken(tt.dollarBraceL)
  2774. } else {
  2775. ++this$1.pos
  2776. return this$1.finishToken(tt.backQuote)
  2777. }
  2778. }
  2779. out += this$1.input.slice(chunkStart, this$1.pos)
  2780. return this$1.finishToken(tt.template, out)
  2781. }
  2782. if (ch === 92) { // '\'
  2783. out += this$1.input.slice(chunkStart, this$1.pos)
  2784. out += this$1.readEscapedChar(true)
  2785. chunkStart = this$1.pos
  2786. } else if (isNewLine(ch)) {
  2787. out += this$1.input.slice(chunkStart, this$1.pos)
  2788. ++this$1.pos
  2789. switch (ch) {
  2790. case 13:
  2791. if (this$1.input.charCodeAt(this$1.pos) === 10) ++this$1.pos
  2792. case 10:
  2793. out += "\n"
  2794. break
  2795. default:
  2796. out += String.fromCharCode(ch)
  2797. break
  2798. }
  2799. if (this$1.options.locations) {
  2800. ++this$1.curLine
  2801. this$1.lineStart = this$1.pos
  2802. }
  2803. chunkStart = this$1.pos
  2804. } else {
  2805. ++this$1.pos
  2806. }
  2807. }
  2808. }
  2809. // Used to read escaped characters
  2810. pp$7.readEscapedChar = function(inTemplate) {
  2811. var ch = this.input.charCodeAt(++this.pos)
  2812. ++this.pos
  2813. switch (ch) {
  2814. case 110: return "\n" // 'n' -> '\n'
  2815. case 114: return "\r" // 'r' -> '\r'
  2816. case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
  2817. case 117: return codePointToString(this.readCodePoint()) // 'u'
  2818. case 116: return "\t" // 't' -> '\t'
  2819. case 98: return "\b" // 'b' -> '\b'
  2820. case 118: return "\u000b" // 'v' -> '\u000b'
  2821. case 102: return "\f" // 'f' -> '\f'
  2822. case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos // '\r\n'
  2823. case 10: // ' \n'
  2824. if (this.options.locations) { this.lineStart = this.pos; ++this.curLine }
  2825. return ""
  2826. default:
  2827. if (ch >= 48 && ch <= 55) {
  2828. var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0]
  2829. var octal = parseInt(octalStr, 8)
  2830. if (octal > 255) {
  2831. octalStr = octalStr.slice(0, -1)
  2832. octal = parseInt(octalStr, 8)
  2833. }
  2834. if (octalStr !== "0" && (this.strict || inTemplate)) {
  2835. this.raise(this.pos - 2, "Octal literal in strict mode")
  2836. }
  2837. this.pos += octalStr.length - 1
  2838. return String.fromCharCode(octal)
  2839. }
  2840. return String.fromCharCode(ch)
  2841. }
  2842. }
  2843. // Used to read character escape sequences ('\x', '\u', '\U').
  2844. pp$7.readHexChar = function(len) {
  2845. var codePos = this.pos
  2846. var n = this.readInt(16, len)
  2847. if (n === null) this.raise(codePos, "Bad character escape sequence")
  2848. return n
  2849. }
  2850. // Read an identifier, and return it as a string. Sets `this.containsEsc`
  2851. // to whether the word contained a '\u' escape.
  2852. //
  2853. // Incrementally adds only escaped chars, adding other chunks as-is
  2854. // as a micro-optimization.
  2855. pp$7.readWord1 = function() {
  2856. var this$1 = this;
  2857. this.containsEsc = false
  2858. var word = "", first = true, chunkStart = this.pos
  2859. var astral = this.options.ecmaVersion >= 6
  2860. while (this.pos < this.input.length) {
  2861. var ch = this$1.fullCharCodeAtPos()
  2862. if (isIdentifierChar(ch, astral)) {
  2863. this$1.pos += ch <= 0xffff ? 1 : 2
  2864. } else if (ch === 92) { // "\"
  2865. this$1.containsEsc = true
  2866. word += this$1.input.slice(chunkStart, this$1.pos)
  2867. var escStart = this$1.pos
  2868. if (this$1.input.charCodeAt(++this$1.pos) != 117) // "u"
  2869. this$1.raise(this$1.pos, "Expecting Unicode escape sequence \\uXXXX")
  2870. ++this$1.pos
  2871. var esc = this$1.readCodePoint()
  2872. if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
  2873. this$1.raise(escStart, "Invalid Unicode escape")
  2874. word += codePointToString(esc)
  2875. chunkStart = this$1.pos
  2876. } else {
  2877. break
  2878. }
  2879. first = false
  2880. }
  2881. return word + this.input.slice(chunkStart, this.pos)
  2882. }
  2883. // Read an identifier or keyword token. Will check for reserved
  2884. // words when necessary.
  2885. pp$7.readWord = function() {
  2886. var word = this.readWord1()
  2887. var type = tt.name
  2888. if (this.keywords.test(word)) {
  2889. if (this.containsEsc) this.raiseRecoverable(this.start, "Escape sequence in keyword " + word)
  2890. type = keywordTypes[word]
  2891. }
  2892. return this.finishToken(type, word)
  2893. }
  2894. // Acorn is a tiny, fast JavaScript parser written in JavaScript.
  2895. //
  2896. // Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
  2897. // various contributors and released under an MIT license.
  2898. //
  2899. // Git repositories for Acorn are available at
  2900. //
  2901. // http://marijnhaverbeke.nl/git/acorn
  2902. // https://github.com/ternjs/acorn.git
  2903. //
  2904. // Please use the [github bug tracker][ghbt] to report issues.
  2905. //
  2906. // [ghbt]: https://github.com/ternjs/acorn/issues
  2907. //
  2908. // This file defines the main parser interface. The library also comes
  2909. // with a [error-tolerant parser][dammit] and an
  2910. // [abstract syntax tree walker][walk], defined in other files.
  2911. //
  2912. // [dammit]: acorn_loose.js
  2913. // [walk]: util/walk.js
  2914. var version = "4.0.11"
  2915. // The main exported interface (under `self.acorn` when in the
  2916. // browser) is a `parse` function that takes a code string and
  2917. // returns an abstract syntax tree as specified by [Mozilla parser
  2918. // API][api].
  2919. //
  2920. // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
  2921. function parse(input, options) {
  2922. return new Parser(options, input).parse()
  2923. }
  2924. // This function tries to parse a single expression at a given
  2925. // offset in a string. Useful for parsing mixed-language formats
  2926. // that embed JavaScript expressions.
  2927. function parseExpressionAt(input, pos, options) {
  2928. var p = new Parser(options, input, pos)
  2929. p.nextToken()
  2930. return p.parseExpression()
  2931. }
  2932. // Acorn is organized as a tokenizer and a recursive-descent parser.
  2933. // The `tokenizer` export provides an interface to the tokenizer.
  2934. function tokenizer(input, options) {
  2935. return new Parser(options, input)
  2936. }
  2937. // This is a terrible kludge to support the existing, pre-ES6
  2938. // interface where the loose parser module retroactively adds exports
  2939. // to this module.
  2940. function addLooseExports(parse, Parser, plugins) {
  2941. parse_dammit = parse
  2942. LooseParser = Parser
  2943. pluginsLoose = plugins
  2944. }
  2945. export { version, parse, parseExpressionAt, tokenizer, parse_dammit, LooseParser, pluginsLoose, addLooseExports, Parser, plugins, defaultOptions, Position, SourceLocation, getLineInfo, Node, TokenType, tt as tokTypes, keywordTypes, TokContext, types as tokContexts, isIdentifierChar, isIdentifierStart, Token, isNewLine, lineBreak, lineBreakG };