acorn.js 123 KB

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