You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

worker-javascript.js 339KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401
  1. "no use strict";
  2. var console = {
  3. log: function(msg) {
  4. postMessage({type: "log", data: msg});
  5. }
  6. };
  7. var window = {
  8. console: console
  9. };
  10. var normalizeModule = function(parentId, moduleName) {
  11. // normalize plugin requires
  12. if (moduleName.indexOf("!") !== -1) {
  13. var chunks = moduleName.split("!");
  14. return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
  15. }
  16. // normalize relative requires
  17. if (moduleName.charAt(0) == ".") {
  18. var base = parentId.split("/").slice(0, -1).join("/");
  19. var moduleName = base + "/" + moduleName;
  20. while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
  21. var previous = moduleName;
  22. var moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
  23. }
  24. }
  25. return moduleName;
  26. };
  27. var require = function(parentId, id) {
  28. var id = normalizeModule(parentId, id);
  29. var module = require.modules[id];
  30. if (module) {
  31. if (!module.initialized) {
  32. module.exports = module.factory().exports;
  33. module.initialized = true;
  34. }
  35. return module.exports;
  36. }
  37. var chunks = id.split("/");
  38. chunks[0] = require.tlns[chunks[0]] || chunks[0];
  39. var path = chunks.join("/") + ".js";
  40. require.id = id;
  41. importScripts(path);
  42. return require(parentId, id);
  43. };
  44. require.modules = {};
  45. require.tlns = {};
  46. var define = function(id, deps, factory) {
  47. if (arguments.length == 2) {
  48. factory = deps;
  49. } else if (arguments.length == 1) {
  50. factory = id;
  51. id = require.id;
  52. }
  53. if (id.indexOf("text!") === 0)
  54. return;
  55. var req = function(deps, factory) {
  56. return require(id, deps, factory);
  57. };
  58. require.modules[id] = {
  59. factory: function() {
  60. var module = {
  61. exports: {}
  62. };
  63. var returnExports = factory(req, module.exports, module);
  64. if (returnExports)
  65. module.exports = returnExports;
  66. return module;
  67. }
  68. };
  69. };
  70. function initBaseUrls(topLevelNamespaces) {
  71. require.tlns = topLevelNamespaces;
  72. }
  73. function initSender() {
  74. var EventEmitter = require(null, "ace/lib/event_emitter").EventEmitter;
  75. var oop = require(null, "ace/lib/oop");
  76. var Sender = function() {};
  77. (function() {
  78. oop.implement(this, EventEmitter);
  79. this.callback = function(data, callbackId) {
  80. postMessage({
  81. type: "call",
  82. id: callbackId,
  83. data: data
  84. });
  85. };
  86. this.emit = function(name, data) {
  87. postMessage({
  88. type: "event",
  89. name: name,
  90. data: data
  91. });
  92. };
  93. }).call(Sender.prototype);
  94. return new Sender();
  95. }
  96. var main;
  97. var sender;
  98. onmessage = function(e) {
  99. var msg = e.data;
  100. if (msg.command) {
  101. main[msg.command].apply(main, msg.args);
  102. }
  103. else if (msg.init) {
  104. initBaseUrls(msg.tlns);
  105. require(null, "ace/lib/fixoldbrowsers");
  106. sender = initSender();
  107. var clazz = require(null, msg.module)[msg.classname];
  108. main = new clazz(sender);
  109. }
  110. else if (msg.event && sender) {
  111. sender._emit(msg.event, msg.data);
  112. }
  113. };
  114. // vim:set ts=4 sts=4 sw=4 st:
  115. // -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
  116. // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project)
  117. // -- dantman Daniel Friesen Copyright(C) 2010 XXX No License Specified
  118. // -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License
  119. // -- Irakli Gozalishvili Copyright (C) 2010 MIT License
  120. /*!
  121. Copyright (c) 2009, 280 North Inc. http://280north.com/
  122. MIT License. http://github.com/280north/narwhal/blob/master/README.md
  123. */
  124. define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/regexp', 'ace/lib/es5-shim'], function(require, exports, module) {
  125. require("./regexp");
  126. require("./es5-shim");
  127. });
  128. define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, exports, module) {
  129. //---------------------------------
  130. // Private variables
  131. //---------------------------------
  132. var real = {
  133. exec: RegExp.prototype.exec,
  134. test: RegExp.prototype.test,
  135. match: String.prototype.match,
  136. replace: String.prototype.replace,
  137. split: String.prototype.split
  138. },
  139. compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
  140. compliantLastIndexIncrement = function () {
  141. var x = /^/g;
  142. real.test.call(x, "");
  143. return !x.lastIndex;
  144. }();
  145. if (compliantLastIndexIncrement && compliantExecNpcg)
  146. return;
  147. //---------------------------------
  148. // Overriden native methods
  149. //---------------------------------
  150. // Adds named capture support (with backreferences returned as `result.name`), and fixes two
  151. // cross-browser issues per ES3:
  152. // - Captured values for nonparticipating capturing groups should be returned as `undefined`,
  153. // rather than the empty string.
  154. // - `lastIndex` should not be incremented after zero-length matches.
  155. RegExp.prototype.exec = function (str) {
  156. var match = real.exec.apply(this, arguments),
  157. name, r2;
  158. if ( typeof(str) == 'string' && match) {
  159. // Fix browsers whose `exec` methods don't consistently return `undefined` for
  160. // nonparticipating capturing groups
  161. if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
  162. r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
  163. // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed
  164. // matching due to characters outside the match
  165. real.replace.call(str.slice(match.index), r2, function () {
  166. for (var i = 1; i < arguments.length - 2; i++) {
  167. if (arguments[i] === undefined)
  168. match[i] = undefined;
  169. }
  170. });
  171. }
  172. // Attach named capture properties
  173. if (this._xregexp && this._xregexp.captureNames) {
  174. for (var i = 1; i < match.length; i++) {
  175. name = this._xregexp.captureNames[i - 1];
  176. if (name)
  177. match[name] = match[i];
  178. }
  179. }
  180. // Fix browsers that increment `lastIndex` after zero-length matches
  181. if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
  182. this.lastIndex--;
  183. }
  184. return match;
  185. };
  186. // Don't override `test` if it won't change anything
  187. if (!compliantLastIndexIncrement) {
  188. // Fix browser bug in native method
  189. RegExp.prototype.test = function (str) {
  190. // Use the native `exec` to skip some processing overhead, even though the overriden
  191. // `exec` would take care of the `lastIndex` fix
  192. var match = real.exec.call(this, str);
  193. // Fix browsers that increment `lastIndex` after zero-length matches
  194. if (match && this.global && !match[0].length && (this.lastIndex > match.index))
  195. this.lastIndex--;
  196. return !!match;
  197. };
  198. }
  199. //---------------------------------
  200. // Private helper functions
  201. //---------------------------------
  202. function getNativeFlags (regex) {
  203. return (regex.global ? "g" : "") +
  204. (regex.ignoreCase ? "i" : "") +
  205. (regex.multiline ? "m" : "") +
  206. (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3
  207. (regex.sticky ? "y" : "");
  208. };
  209. function indexOf (array, item, from) {
  210. if (Array.prototype.indexOf) // Use the native array method if available
  211. return array.indexOf(item, from);
  212. for (var i = from || 0; i < array.length; i++) {
  213. if (array[i] === item)
  214. return i;
  215. }
  216. return -1;
  217. };
  218. });
  219. // vim: ts=4 sts=4 sw=4 expandtab
  220. // -- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License
  221. // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project)
  222. // -- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA
  223. // -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License
  224. // -- Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License
  225. // -- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License
  226. // -- kossnocorp Sasha Koss XXX TODO License or CLA
  227. // -- bryanforbes Bryan Forbes XXX TODO License or CLA
  228. // -- killdream Quildreen Motta Copyright (C) 2011 MIT Licence
  229. // -- michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD License
  230. // -- sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License
  231. // -- bbqsrc Brendan Molloy (C) 2011 Creative Commons Zero (public domain)
  232. // -- iwyg XXX TODO License or CLA
  233. // -- DomenicDenicola Domenic Denicola Copyright (C) 2011 MIT License
  234. // -- xavierm02 Montillet Xavier XXX TODO License or CLA
  235. // -- Raynos Raynos XXX TODO License or CLA
  236. // -- samsonjs Sami Samhuri Copyright (C) 2010 MIT License
  237. // -- rwldrn Rick Waldron Copyright (C) 2011 MIT License
  238. // -- lexer Alexey Zakharov XXX TODO License or CLA
  239. /*!
  240. Copyright (c) 2009, 280 North Inc. http://280north.com/
  241. MIT License. http://github.com/280north/narwhal/blob/master/README.md
  242. */
  243. define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
  244. /*
  245. * Brings an environment as close to ECMAScript 5 compliance
  246. * as is possible with the facilities of erstwhile engines.
  247. *
  248. * Annotated ES5: http://es5.github.com/ (specific links below)
  249. * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
  250. *
  251. * @module
  252. */
  253. /*whatsupdoc*/
  254. //
  255. // Function
  256. // ========
  257. //
  258. // ES-5 15.3.4.5
  259. // http://es5.github.com/#x15.3.4.5
  260. if (!Function.prototype.bind) {
  261. Function.prototype.bind = function bind(that) { // .length is 1
  262. // 1. Let Target be the this value.
  263. var target = this;
  264. // 2. If IsCallable(Target) is false, throw a TypeError exception.
  265. if (typeof target != "function")
  266. throw new TypeError(); // TODO message
  267. // 3. Let A be a new (possibly empty) internal list of all of the
  268. // argument values provided after thisArg (arg1, arg2 etc), in order.
  269. // XXX slicedArgs will stand in for "A" if used
  270. var args = slice.call(arguments, 1); // for normal call
  271. // 4. Let F be a new native ECMAScript object.
  272. // 11. Set the [[Prototype]] internal property of F to the standard
  273. // built-in Function prototype object as specified in 15.3.3.1.
  274. // 12. Set the [[Call]] internal property of F as described in
  275. // 15.3.4.5.1.
  276. // 13. Set the [[Construct]] internal property of F as described in
  277. // 15.3.4.5.2.
  278. // 14. Set the [[HasInstance]] internal property of F as described in
  279. // 15.3.4.5.3.
  280. var bound = function () {
  281. if (this instanceof bound) {
  282. // 15.3.4.5.2 [[Construct]]
  283. // When the [[Construct]] internal method of a function object,
  284. // F that was created using the bind function is called with a
  285. // list of arguments ExtraArgs, the following steps are taken:
  286. // 1. Let target be the value of F's [[TargetFunction]]
  287. // internal property.
  288. // 2. If target has no [[Construct]] internal method, a
  289. // TypeError exception is thrown.
  290. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
  291. // property.
  292. // 4. Let args be a new list containing the same values as the
  293. // list boundArgs in the same order followed by the same
  294. // values as the list ExtraArgs in the same order.
  295. // 5. Return the result of calling the [[Construct]] internal
  296. // method of target providing args as the arguments.
  297. var F = function(){};
  298. F.prototype = target.prototype;
  299. var self = new F;
  300. var result = target.apply(
  301. self,
  302. args.concat(slice.call(arguments))
  303. );
  304. if (result !== null && Object(result) === result)
  305. return result;
  306. return self;
  307. } else {
  308. // 15.3.4.5.1 [[Call]]
  309. // When the [[Call]] internal method of a function object, F,
  310. // which was created using the bind function is called with a
  311. // this value and a list of arguments ExtraArgs, the following
  312. // steps are taken:
  313. // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
  314. // property.
  315. // 2. Let boundThis be the value of F's [[BoundThis]] internal
  316. // property.
  317. // 3. Let target be the value of F's [[TargetFunction]] internal
  318. // property.
  319. // 4. Let args be a new list containing the same values as the
  320. // list boundArgs in the same order followed by the same
  321. // values as the list ExtraArgs in the same order.
  322. // 5. Return the result of calling the [[Call]] internal method
  323. // of target providing boundThis as the this value and
  324. // providing args as the arguments.
  325. // equiv: target.call(this, ...boundArgs, ...args)
  326. return target.apply(
  327. that,
  328. args.concat(slice.call(arguments))
  329. );
  330. }
  331. };
  332. // XXX bound.length is never writable, so don't even try
  333. //
  334. // 15. If the [[Class]] internal property of Target is "Function", then
  335. // a. Let L be the length property of Target minus the length of A.
  336. // b. Set the length own property of F to either 0 or L, whichever is
  337. // larger.
  338. // 16. Else set the length own property of F to 0.
  339. // 17. Set the attributes of the length own property of F to the values
  340. // specified in 15.3.5.1.
  341. // TODO
  342. // 18. Set the [[Extensible]] internal property of F to true.
  343. // TODO
  344. // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
  345. // 20. Call the [[DefineOwnProperty]] internal method of F with
  346. // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
  347. // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
  348. // false.
  349. // 21. Call the [[DefineOwnProperty]] internal method of F with
  350. // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
  351. // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
  352. // and false.
  353. // TODO
  354. // NOTE Function objects created using Function.prototype.bind do not
  355. // have a prototype property or the [[Code]], [[FormalParameters]], and
  356. // [[Scope]] internal properties.
  357. // XXX can't delete prototype in pure-js.
  358. // 22. Return F.
  359. return bound;
  360. };
  361. }
  362. // Shortcut to an often accessed properties, in order to avoid multiple
  363. // dereference that costs universally.
  364. // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
  365. // us it in defining shortcuts.
  366. var call = Function.prototype.call;
  367. var prototypeOfArray = Array.prototype;
  368. var prototypeOfObject = Object.prototype;
  369. var slice = prototypeOfArray.slice;
  370. var toString = call.bind(prototypeOfObject.toString);
  371. var owns = call.bind(prototypeOfObject.hasOwnProperty);
  372. // If JS engine supports accessors creating shortcuts.
  373. var defineGetter;
  374. var defineSetter;
  375. var lookupGetter;
  376. var lookupSetter;
  377. var supportsAccessors;
  378. if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
  379. defineGetter = call.bind(prototypeOfObject.__defineGetter__);
  380. defineSetter = call.bind(prototypeOfObject.__defineSetter__);
  381. lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
  382. lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
  383. }
  384. //
  385. // Array
  386. // =====
  387. //
  388. // ES5 15.4.3.2
  389. // http://es5.github.com/#x15.4.3.2
  390. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
  391. if (!Array.isArray) {
  392. Array.isArray = function isArray(obj) {
  393. return toString(obj) == "[object Array]";
  394. };
  395. }
  396. // The IsCallable() check in the Array functions
  397. // has been replaced with a strict check on the
  398. // internal class of the object to trap cases where
  399. // the provided function was actually a regular
  400. // expression literal, which in V8 and
  401. // JavaScriptCore is a typeof "function". Only in
  402. // V8 are regular expression literals permitted as
  403. // reduce parameters, so it is desirable in the
  404. // general case for the shim to match the more
  405. // strict and common behavior of rejecting regular
  406. // expressions.
  407. // ES5 15.4.4.18
  408. // http://es5.github.com/#x15.4.4.18
  409. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
  410. if (!Array.prototype.forEach) {
  411. Array.prototype.forEach = function forEach(fun /*, thisp*/) {
  412. var self = toObject(this),
  413. thisp = arguments[1],
  414. i = 0,
  415. length = self.length >>> 0;
  416. // If no callback function or if callback is not a callable function
  417. if (toString(fun) != "[object Function]") {
  418. throw new TypeError(); // TODO message
  419. }
  420. while (i < length) {
  421. if (i in self) {
  422. // Invoke the callback function with call, passing arguments:
  423. // context, property value, property key, thisArg object context
  424. fun.call(thisp, self[i], i, self);
  425. }
  426. i++;
  427. }
  428. };
  429. }
  430. // ES5 15.4.4.19
  431. // http://es5.github.com/#x15.4.4.19
  432. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  433. if (!Array.prototype.map) {
  434. Array.prototype.map = function map(fun /*, thisp*/) {
  435. var self = toObject(this),
  436. length = self.length >>> 0,
  437. result = Array(length),
  438. thisp = arguments[1];
  439. // If no callback function or if callback is not a callable function
  440. if (toString(fun) != "[object Function]") {
  441. throw new TypeError(); // TODO message
  442. }
  443. for (var i = 0; i < length; i++) {
  444. if (i in self)
  445. result[i] = fun.call(thisp, self[i], i, self);
  446. }
  447. return result;
  448. };
  449. }
  450. // ES5 15.4.4.20
  451. // http://es5.github.com/#x15.4.4.20
  452. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
  453. if (!Array.prototype.filter) {
  454. Array.prototype.filter = function filter(fun /*, thisp */) {
  455. var self = toObject(this),
  456. length = self.length >>> 0,
  457. result = [],
  458. thisp = arguments[1];
  459. // If no callback function or if callback is not a callable function
  460. if (toString(fun) != "[object Function]") {
  461. throw new TypeError(); // TODO message
  462. }
  463. for (var i = 0; i < length; i++) {
  464. if (i in self && fun.call(thisp, self[i], i, self))
  465. result.push(self[i]);
  466. }
  467. return result;
  468. };
  469. }
  470. // ES5 15.4.4.16
  471. // http://es5.github.com/#x15.4.4.16
  472. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
  473. if (!Array.prototype.every) {
  474. Array.prototype.every = function every(fun /*, thisp */) {
  475. var self = toObject(this),
  476. length = self.length >>> 0,
  477. thisp = arguments[1];
  478. // If no callback function or if callback is not a callable function
  479. if (toString(fun) != "[object Function]") {
  480. throw new TypeError(); // TODO message
  481. }
  482. for (var i = 0; i < length; i++) {
  483. if (i in self && !fun.call(thisp, self[i], i, self))
  484. return false;
  485. }
  486. return true;
  487. };
  488. }
  489. // ES5 15.4.4.17
  490. // http://es5.github.com/#x15.4.4.17
  491. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
  492. if (!Array.prototype.some) {
  493. Array.prototype.some = function some(fun /*, thisp */) {
  494. var self = toObject(this),
  495. length = self.length >>> 0,
  496. thisp = arguments[1];
  497. // If no callback function or if callback is not a callable function
  498. if (toString(fun) != "[object Function]") {
  499. throw new TypeError(); // TODO message
  500. }
  501. for (var i = 0; i < length; i++) {
  502. if (i in self && fun.call(thisp, self[i], i, self))
  503. return true;
  504. }
  505. return false;
  506. };
  507. }
  508. // ES5 15.4.4.21
  509. // http://es5.github.com/#x15.4.4.21
  510. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
  511. if (!Array.prototype.reduce) {
  512. Array.prototype.reduce = function reduce(fun /*, initial*/) {
  513. var self = toObject(this),
  514. length = self.length >>> 0;
  515. // If no callback function or if callback is not a callable function
  516. if (toString(fun) != "[object Function]") {
  517. throw new TypeError(); // TODO message
  518. }
  519. // no value to return if no initial value and an empty array
  520. if (!length && arguments.length == 1)
  521. throw new TypeError(); // TODO message
  522. var i = 0;
  523. var result;
  524. if (arguments.length >= 2) {
  525. result = arguments[1];
  526. } else {
  527. do {
  528. if (i in self) {
  529. result = self[i++];
  530. break;
  531. }
  532. // if array contains no values, no initial value to return
  533. if (++i >= length)
  534. throw new TypeError(); // TODO message
  535. } while (true);
  536. }
  537. for (; i < length; i++) {
  538. if (i in self)
  539. result = fun.call(void 0, result, self[i], i, self);
  540. }
  541. return result;
  542. };
  543. }
  544. // ES5 15.4.4.22
  545. // http://es5.github.com/#x15.4.4.22
  546. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
  547. if (!Array.prototype.reduceRight) {
  548. Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
  549. var self = toObject(this),
  550. length = self.length >>> 0;
  551. // If no callback function or if callback is not a callable function
  552. if (toString(fun) != "[object Function]") {
  553. throw new TypeError(); // TODO message
  554. }
  555. // no value to return if no initial value, empty array
  556. if (!length && arguments.length == 1)
  557. throw new TypeError(); // TODO message
  558. var result, i = length - 1;
  559. if (arguments.length >= 2) {
  560. result = arguments[1];
  561. } else {
  562. do {
  563. if (i in self) {
  564. result = self[i--];
  565. break;
  566. }
  567. // if array contains no values, no initial value to return
  568. if (--i < 0)
  569. throw new TypeError(); // TODO message
  570. } while (true);
  571. }
  572. do {
  573. if (i in this)
  574. result = fun.call(void 0, result, self[i], i, self);
  575. } while (i--);
  576. return result;
  577. };
  578. }
  579. // ES5 15.4.4.14
  580. // http://es5.github.com/#x15.4.4.14
  581. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
  582. if (!Array.prototype.indexOf) {
  583. Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
  584. var self = toObject(this),
  585. length = self.length >>> 0;
  586. if (!length)
  587. return -1;
  588. var i = 0;
  589. if (arguments.length > 1)
  590. i = toInteger(arguments[1]);
  591. // handle negative indices
  592. i = i >= 0 ? i : Math.max(0, length + i);
  593. for (; i < length; i++) {
  594. if (i in self && self[i] === sought) {
  595. return i;
  596. }
  597. }
  598. return -1;
  599. };
  600. }
  601. // ES5 15.4.4.15
  602. // http://es5.github.com/#x15.4.4.15
  603. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
  604. if (!Array.prototype.lastIndexOf) {
  605. Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
  606. var self = toObject(this),
  607. length = self.length >>> 0;
  608. if (!length)
  609. return -1;
  610. var i = length - 1;
  611. if (arguments.length > 1)
  612. i = Math.min(i, toInteger(arguments[1]));
  613. // handle negative indices
  614. i = i >= 0 ? i : length - Math.abs(i);
  615. for (; i >= 0; i--) {
  616. if (i in self && sought === self[i])
  617. return i;
  618. }
  619. return -1;
  620. };
  621. }
  622. //
  623. // Object
  624. // ======
  625. //
  626. // ES5 15.2.3.2
  627. // http://es5.github.com/#x15.2.3.2
  628. if (!Object.getPrototypeOf) {
  629. // https://github.com/kriskowal/es5-shim/issues#issue/2
  630. // http://ejohn.org/blog/objectgetprototypeof/
  631. // recommended by fschaefer on github
  632. Object.getPrototypeOf = function getPrototypeOf(object) {
  633. return object.__proto__ || (
  634. object.constructor ?
  635. object.constructor.prototype :
  636. prototypeOfObject
  637. );
  638. };
  639. }
  640. // ES5 15.2.3.3
  641. // http://es5.github.com/#x15.2.3.3
  642. if (!Object.getOwnPropertyDescriptor) {
  643. var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
  644. "non-object: ";
  645. Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
  646. if ((typeof object != "object" && typeof object != "function") || object === null)
  647. throw new TypeError(ERR_NON_OBJECT + object);
  648. // If object does not owns property return undefined immediately.
  649. if (!owns(object, property))
  650. return;
  651. var descriptor, getter, setter;
  652. // If object has a property then it's for sure both `enumerable` and
  653. // `configurable`.
  654. descriptor = { enumerable: true, configurable: true };
  655. // If JS engine supports accessor properties then property may be a
  656. // getter or setter.
  657. if (supportsAccessors) {
  658. // Unfortunately `__lookupGetter__` will return a getter even
  659. // if object has own non getter property along with a same named
  660. // inherited getter. To avoid misbehavior we temporary remove
  661. // `__proto__` so that `__lookupGetter__` will return getter only
  662. // if it's owned by an object.
  663. var prototype = object.__proto__;
  664. object.__proto__ = prototypeOfObject;
  665. var getter = lookupGetter(object, property);
  666. var setter = lookupSetter(object, property);
  667. // Once we have getter and setter we can put values back.
  668. object.__proto__ = prototype;
  669. if (getter || setter) {
  670. if (getter) descriptor.get = getter;
  671. if (setter) descriptor.set = setter;
  672. // If it was accessor property we're done and return here
  673. // in order to avoid adding `value` to the descriptor.
  674. return descriptor;
  675. }
  676. }
  677. // If we got this far we know that object has an own property that is
  678. // not an accessor so we set it as a value and return descriptor.
  679. descriptor.value = object[property];
  680. return descriptor;
  681. };
  682. }
  683. // ES5 15.2.3.4
  684. // http://es5.github.com/#x15.2.3.4
  685. if (!Object.getOwnPropertyNames) {
  686. Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
  687. return Object.keys(object);
  688. };
  689. }
  690. // ES5 15.2.3.5
  691. // http://es5.github.com/#x15.2.3.5
  692. if (!Object.create) {
  693. Object.create = function create(prototype, properties) {
  694. var object;
  695. if (prototype === null) {
  696. object = { "__proto__": null };
  697. } else {
  698. if (typeof prototype != "object")
  699. throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
  700. var Type = function () {};
  701. Type.prototype = prototype;
  702. object = new Type();
  703. // IE has no built-in implementation of `Object.getPrototypeOf`
  704. // neither `__proto__`, but this manually setting `__proto__` will
  705. // guarantee that `Object.getPrototypeOf` will work as expected with
  706. // objects created using `Object.create`
  707. object.__proto__ = prototype;
  708. }
  709. if (properties !== void 0)
  710. Object.defineProperties(object, properties);
  711. return object;
  712. };
  713. }
  714. // ES5 15.2.3.6
  715. // http://es5.github.com/#x15.2.3.6
  716. // Patch for WebKit and IE8 standard mode
  717. // Designed by hax <hax.github.com>
  718. // related issue: https://github.com/kriskowal/es5-shim/issues#issue/5
  719. // IE8 Reference:
  720. // http://msdn.microsoft.com/en-us/library/dd282900.aspx
  721. // http://msdn.microsoft.com/en-us/library/dd229916.aspx
  722. // WebKit Bugs:
  723. // https://bugs.webkit.org/show_bug.cgi?id=36423
  724. function doesDefinePropertyWork(object) {
  725. try {
  726. Object.defineProperty(object, "sentinel", {});
  727. return "sentinel" in object;
  728. } catch (exception) {
  729. // returns falsy
  730. }
  731. }
  732. // check whether defineProperty works if it's given. Otherwise,
  733. // shim partially.
  734. if (Object.defineProperty) {
  735. var definePropertyWorksOnObject = doesDefinePropertyWork({});
  736. var definePropertyWorksOnDom = typeof document == "undefined" ||
  737. doesDefinePropertyWork(document.createElement("div"));
  738. if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
  739. var definePropertyFallback = Object.defineProperty;
  740. }
  741. }
  742. if (!Object.defineProperty || definePropertyFallback) {
  743. var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
  744. var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
  745. var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
  746. "on this javascript engine";
  747. Object.defineProperty = function defineProperty(object, property, descriptor) {
  748. if ((typeof object != "object" && typeof object != "function") || object === null)
  749. throw new TypeError(ERR_NON_OBJECT_TARGET + object);
  750. if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
  751. throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
  752. // make a valiant attempt to use the real defineProperty
  753. // for I8's DOM elements.
  754. if (definePropertyFallback) {
  755. try {
  756. return definePropertyFallback.call(Object, object, property, descriptor);
  757. } catch (exception) {
  758. // try the shim if the real one doesn't work
  759. }
  760. }
  761. // If it's a data property.
  762. if (owns(descriptor, "value")) {
  763. // fail silently if "writable", "enumerable", or "configurable"
  764. // are requested but not supported
  765. /*
  766. // alternate approach:
  767. if ( // can't implement these features; allow false but not true
  768. !(owns(descriptor, "writable") ? descriptor.writable : true) ||
  769. !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) ||
  770. !(owns(descriptor, "configurable") ? descriptor.configurable : true)
  771. )
  772. throw new RangeError(
  773. "This implementation of Object.defineProperty does not " +
  774. "support configurable, enumerable, or writable."
  775. );
  776. */
  777. if (supportsAccessors && (lookupGetter(object, property) ||
  778. lookupSetter(object, property)))
  779. {
  780. // As accessors are supported only on engines implementing
  781. // `__proto__` we can safely override `__proto__` while defining
  782. // a property to make sure that we don't hit an inherited
  783. // accessor.
  784. var prototype = object.__proto__;
  785. object.__proto__ = prototypeOfObject;
  786. // Deleting a property anyway since getter / setter may be
  787. // defined on object itself.
  788. delete object[property];
  789. object[property] = descriptor.value;
  790. // Setting original `__proto__` back now.
  791. object.__proto__ = prototype;
  792. } else {
  793. object[property] = descriptor.value;
  794. }
  795. } else {
  796. if (!supportsAccessors)
  797. throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
  798. // If we got that far then getters and setters can be defined !!
  799. if (owns(descriptor, "get"))
  800. defineGetter(object, property, descriptor.get);
  801. if (owns(descriptor, "set"))
  802. defineSetter(object, property, descriptor.set);
  803. }
  804. return object;
  805. };
  806. }
  807. // ES5 15.2.3.7
  808. // http://es5.github.com/#x15.2.3.7
  809. if (!Object.defineProperties) {
  810. Object.defineProperties = function defineProperties(object, properties) {
  811. for (var property in properties) {
  812. if (owns(properties, property))
  813. Object.defineProperty(object, property, properties[property]);
  814. }
  815. return object;
  816. };
  817. }
  818. // ES5 15.2.3.8
  819. // http://es5.github.com/#x15.2.3.8
  820. if (!Object.seal) {
  821. Object.seal = function seal(object) {
  822. // this is misleading and breaks feature-detection, but
  823. // allows "securable" code to "gracefully" degrade to working
  824. // but insecure code.
  825. return object;
  826. };
  827. }
  828. // ES5 15.2.3.9
  829. // http://es5.github.com/#x15.2.3.9
  830. if (!Object.freeze) {
  831. Object.freeze = function freeze(object) {
  832. // this is misleading and breaks feature-detection, but
  833. // allows "securable" code to "gracefully" degrade to working
  834. // but insecure code.
  835. return object;
  836. };
  837. }
  838. // detect a Rhino bug and patch it
  839. try {
  840. Object.freeze(function () {});
  841. } catch (exception) {
  842. Object.freeze = (function freeze(freezeObject) {
  843. return function freeze(object) {
  844. if (typeof object == "function") {
  845. return object;
  846. } else {
  847. return freezeObject(object);
  848. }
  849. };
  850. })(Object.freeze);
  851. }
  852. // ES5 15.2.3.10
  853. // http://es5.github.com/#x15.2.3.10
  854. if (!Object.preventExtensions) {
  855. Object.preventExtensions = function preventExtensions(object) {
  856. // this is misleading and breaks feature-detection, but
  857. // allows "securable" code to "gracefully" degrade to working
  858. // but insecure code.
  859. return object;
  860. };
  861. }
  862. // ES5 15.2.3.11
  863. // http://es5.github.com/#x15.2.3.11
  864. if (!Object.isSealed) {
  865. Object.isSealed = function isSealed(object) {
  866. return false;
  867. };
  868. }
  869. // ES5 15.2.3.12
  870. // http://es5.github.com/#x15.2.3.12
  871. if (!Object.isFrozen) {
  872. Object.isFrozen = function isFrozen(object) {
  873. return false;
  874. };
  875. }
  876. // ES5 15.2.3.13
  877. // http://es5.github.com/#x15.2.3.13
  878. if (!Object.isExtensible) {
  879. Object.isExtensible = function isExtensible(object) {
  880. // 1. If Type(O) is not Object throw a TypeError exception.
  881. if (Object(object) === object) {
  882. throw new TypeError(); // TODO message
  883. }
  884. // 2. Return the Boolean value of the [[Extensible]] internal property of O.
  885. var name = '';
  886. while (owns(object, name)) {
  887. name += '?';
  888. }
  889. object[name] = true;
  890. var returnValue = owns(object, name);
  891. delete object[name];
  892. return returnValue;
  893. };
  894. }
  895. // ES5 15.2.3.14
  896. // http://es5.github.com/#x15.2.3.14
  897. if (!Object.keys) {
  898. // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
  899. var hasDontEnumBug = true,
  900. dontEnums = [
  901. "toString",
  902. "toLocaleString",
  903. "valueOf",
  904. "hasOwnProperty",
  905. "isPrototypeOf",
  906. "propertyIsEnumerable",
  907. "constructor"
  908. ],
  909. dontEnumsLength = dontEnums.length;
  910. for (var key in {"toString": null})
  911. hasDontEnumBug = false;
  912. Object.keys = function keys(object) {
  913. if ((typeof object != "object" && typeof object != "function") || object === null)
  914. throw new TypeError("Object.keys called on a non-object");
  915. var keys = [];
  916. for (var name in object) {
  917. if (owns(object, name)) {
  918. keys.push(name);
  919. }
  920. }
  921. if (hasDontEnumBug) {
  922. for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
  923. var dontEnum = dontEnums[i];
  924. if (owns(object, dontEnum)) {
  925. keys.push(dontEnum);
  926. }
  927. }
  928. }
  929. return keys;
  930. };
  931. }
  932. //
  933. // Date
  934. // ====
  935. //
  936. // ES5 15.9.5.43
  937. // http://es5.github.com/#x15.9.5.43
  938. // This function returns a String value represent the instance in time
  939. // represented by this Date object. The format of the String is the Date Time
  940. // string format defined in 15.9.1.15. All fields are present in the String.
  941. // The time zone is always UTC, denoted by the suffix Z. If the time value of
  942. // this object is not a finite Number a RangeError exception is thrown.
  943. if (!Date.prototype.toISOString || (new Date(-62198755200000).toISOString().indexOf('-000001') === -1)) {
  944. Date.prototype.toISOString = function toISOString() {
  945. var result, length, value, year;
  946. if (!isFinite(this))
  947. throw new RangeError;
  948. // the date time string format is specified in 15.9.1.15.
  949. result = [this.getUTCMonth() + 1, this.getUTCDate(),
  950. this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
  951. year = this.getUTCFullYear();
  952. year = (year < 0 ? '-' : (year > 9999 ? '+' : '')) + ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6);
  953. length = result.length;
  954. while (length--) {
  955. value = result[length];
  956. // pad months, days, hours, minutes, and seconds to have two digits.
  957. if (value < 10)
  958. result[length] = "0" + value;
  959. }
  960. // pad milliseconds to have three digits.
  961. return year + "-" + result.slice(0, 2).join("-") + "T" + result.slice(2).join(":") + "." +
  962. ("000" + this.getUTCMilliseconds()).slice(-3) + "Z";
  963. }
  964. }
  965. // ES5 15.9.4.4
  966. // http://es5.github.com/#x15.9.4.4
  967. if (!Date.now) {
  968. Date.now = function now() {
  969. return new Date().getTime();
  970. };
  971. }
  972. // ES5 15.9.5.44
  973. // http://es5.github.com/#x15.9.5.44
  974. // This function provides a String representation of a Date object for use by
  975. // JSON.stringify (15.12.3).
  976. if (!Date.prototype.toJSON) {
  977. Date.prototype.toJSON = function toJSON(key) {
  978. // When the toJSON method is called with argument key, the following
  979. // steps are taken:
  980. // 1. Let O be the result of calling ToObject, giving it the this
  981. // value as its argument.
  982. // 2. Let tv be ToPrimitive(O, hint Number).
  983. // 3. If tv is a Number and is not finite, return null.
  984. // XXX
  985. // 4. Let toISO be the result of calling the [[Get]] internal method of
  986. // O with argument "toISOString".
  987. // 5. If IsCallable(toISO) is false, throw a TypeError exception.
  988. if (typeof this.toISOString != "function")
  989. throw new TypeError(); // TODO message
  990. // 6. Return the result of calling the [[Call]] internal method of
  991. // toISO with O as the this value and an empty argument list.
  992. return this.toISOString();
  993. // NOTE 1 The argument is ignored.
  994. // NOTE 2 The toJSON function is intentionally generic; it does not
  995. // require that its this value be a Date object. Therefore, it can be
  996. // transferred to other kinds of objects for use as a method. However,
  997. // it does require that any such object have a toISOString method. An
  998. // object is free to use the argument key to filter its
  999. // stringification.
  1000. };
  1001. }
  1002. // ES5 15.9.4.2
  1003. // http://es5.github.com/#x15.9.4.2
  1004. // based on work shared by Daniel Friesen (dantman)
  1005. // http://gist.github.com/303249
  1006. if (Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) {
  1007. // XXX global assignment won't work in embeddings that use
  1008. // an alternate object for the context.
  1009. Date = (function(NativeDate) {
  1010. // Date.length === 7
  1011. var Date = function Date(Y, M, D, h, m, s, ms) {
  1012. var length = arguments.length;
  1013. if (this instanceof NativeDate) {
  1014. var date = length == 1 && String(Y) === Y ? // isString(Y)
  1015. // We explicitly pass it through parse:
  1016. new NativeDate(Date.parse(Y)) :
  1017. // We have to manually make calls depending on argument
  1018. // length here
  1019. length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
  1020. length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
  1021. length >= 5 ? new NativeDate(Y, M, D, h, m) :
  1022. length >= 4 ? new NativeDate(Y, M, D, h) :
  1023. length >= 3 ? new NativeDate(Y, M, D) :
  1024. length >= 2 ? new NativeDate(Y, M) :
  1025. length >= 1 ? new NativeDate(Y) :
  1026. new NativeDate();
  1027. // Prevent mixups with unfixed Date object
  1028. date.constructor = Date;
  1029. return date;
  1030. }
  1031. return NativeDate.apply(this, arguments);
  1032. };
  1033. // 15.9.1.15 Date Time String Format.
  1034. var isoDateExpression = new RegExp("^" +
  1035. "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + 6-digit extended year
  1036. "(?:-(\\d{2})" + // optional month capture
  1037. "(?:-(\\d{2})" + // optional day capture
  1038. "(?:" + // capture hours:minutes:seconds.milliseconds
  1039. "T(\\d{2})" + // hours capture
  1040. ":(\\d{2})" + // minutes capture
  1041. "(?:" + // optional :seconds.milliseconds
  1042. ":(\\d{2})" + // seconds capture
  1043. "(?:\\.(\\d{3}))?" + // milliseconds capture
  1044. ")?" +
  1045. "(?:" + // capture UTC offset component
  1046. "Z|" + // UTC capture
  1047. "(?:" + // offset specifier +/-hours:minutes
  1048. "([-+])" + // sign capture
  1049. "(\\d{2})" + // hours offset capture
  1050. ":(\\d{2})" + // minutes offset capture
  1051. ")" +
  1052. ")?)?)?)?" +
  1053. "$");
  1054. // Copy any custom methods a 3rd party library may have added
  1055. for (var key in NativeDate)
  1056. Date[key] = NativeDate[key];
  1057. // Copy "native" methods explicitly; they may be non-enumerable
  1058. Date.now = NativeDate.now;
  1059. Date.UTC = NativeDate.UTC;
  1060. Date.prototype = NativeDate.prototype;
  1061. Date.prototype.constructor = Date;
  1062. // Upgrade Date.parse to handle simplified ISO 8601 strings
  1063. Date.parse = function parse(string) {
  1064. var match = isoDateExpression.exec(string);
  1065. if (match) {
  1066. match.shift(); // kill match[0], the full match
  1067. // parse months, days, hours, minutes, seconds, and milliseconds
  1068. for (var i = 1; i < 7; i++) {
  1069. // provide default values if necessary
  1070. match[i] = +(match[i] || (i < 3 ? 1 : 0));
  1071. // match[1] is the month. Months are 0-11 in JavaScript
  1072. // `Date` objects, but 1-12 in ISO notation, so we
  1073. // decrement.
  1074. if (i == 1)
  1075. match[i]--;
  1076. }
  1077. // parse the UTC offset component
  1078. var minuteOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop();
  1079. // compute the explicit time zone offset if specified
  1080. var offset = 0;
  1081. if (sign) {
  1082. // detect invalid offsets and return early
  1083. if (hourOffset > 23 || minuteOffset > 59)
  1084. return NaN;
  1085. // express the provided time zone offset in minutes. The offset is
  1086. // negative for time zones west of UTC; positive otherwise.
  1087. offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1);
  1088. }
  1089. // Date.UTC for years between 0 and 99 converts year to 1900 + year
  1090. // The Gregorian calendar has a 400-year cycle, so
  1091. // to Date.UTC(year + 400, .... ) - 12622780800000 == Date.UTC(year, ...),
  1092. // where 12622780800000 - number of milliseconds in Gregorian calendar 400 years
  1093. var year = +match[0];
  1094. if (0 <= year && year <= 99) {
  1095. match[0] = year + 400;
  1096. return NativeDate.UTC.apply(this, match) + offset - 12622780800000;
  1097. }
  1098. // compute a new UTC date value, accounting for the optional offset
  1099. return NativeDate.UTC.apply(this, match) + offset;
  1100. }
  1101. return NativeDate.parse.apply(this, arguments);
  1102. };
  1103. return Date;
  1104. })(Date);
  1105. }
  1106. //
  1107. // String
  1108. // ======
  1109. //
  1110. // ES5 15.5.4.20
  1111. // http://es5.github.com/#x15.5.4.20
  1112. var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
  1113. "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
  1114. "\u2029\uFEFF";
  1115. if (!String.prototype.trim || ws.trim()) {
  1116. // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  1117. // http://perfectionkills.com/whitespace-deviations/
  1118. ws = "[" + ws + "]";
  1119. var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
  1120. trimEndRegexp = new RegExp(ws + ws + "*$");
  1121. String.prototype.trim = function trim() {
  1122. return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
  1123. };
  1124. }
  1125. //
  1126. // Util
  1127. // ======
  1128. //
  1129. // ES5 9.4
  1130. // http://es5.github.com/#x9.4
  1131. // http://jsperf.com/to-integer
  1132. var toInteger = function (n) {
  1133. n = +n;
  1134. if (n !== n) // isNaN
  1135. n = 0;
  1136. else if (n !== 0 && n !== (1/0) && n !== -(1/0))
  1137. n = (n > 0 || -1) * Math.floor(Math.abs(n));
  1138. return n;
  1139. };
  1140. var prepareString = "a"[0] != "a",
  1141. // ES5 9.9
  1142. // http://es5.github.com/#x9.9
  1143. toObject = function (o) {
  1144. if (o == null) { // this matches both null and undefined
  1145. throw new TypeError(); // TODO message
  1146. }
  1147. // If the implementation doesn't support by-index access of
  1148. // string characters (ex. IE < 7), split the string
  1149. if (prepareString && typeof o == "string" && o) {
  1150. return o.split("");
  1151. }
  1152. return Object(o);
  1153. };
  1154. });
  1155. define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
  1156. var EventEmitter = {};
  1157. EventEmitter._emit =
  1158. EventEmitter._dispatchEvent = function(eventName, e) {
  1159. this._eventRegistry = this._eventRegistry || {};
  1160. this._defaultHandlers = this._defaultHandlers || {};
  1161. var listeners = this._eventRegistry[eventName] || [];
  1162. var defaultHandler = this._defaultHandlers[eventName];
  1163. if (!listeners.length && !defaultHandler)
  1164. return;
  1165. e = e || {};
  1166. e.type = eventName;
  1167. if (!e.stopPropagation) {
  1168. e.stopPropagation = function() {
  1169. this.propagationStopped = true;
  1170. };
  1171. }
  1172. if (!e.preventDefault) {
  1173. e.preventDefault = function() {
  1174. this.defaultPrevented = true;
  1175. };
  1176. }
  1177. for (var i=0; i<listeners.length; i++) {
  1178. listeners[i](e);
  1179. if (e.propagationStopped)
  1180. break;
  1181. }
  1182. if (defaultHandler && !e.defaultPrevented)
  1183. return defaultHandler(e);
  1184. };
  1185. EventEmitter.setDefaultHandler = function(eventName, callback) {
  1186. this._defaultHandlers = this._defaultHandlers || {};
  1187. if (this._defaultHandlers[eventName])
  1188. throw new Error("The default handler for '" + eventName + "' is already set");
  1189. this._defaultHandlers[eventName] = callback;
  1190. };
  1191. EventEmitter.on =
  1192. EventEmitter.addEventListener = function(eventName, callback) {
  1193. this._eventRegistry = this._eventRegistry || {};
  1194. var listeners = this._eventRegistry[eventName];
  1195. if (!listeners)
  1196. var listeners = this._eventRegistry[eventName] = [];
  1197. if (listeners.indexOf(callback) == -1)
  1198. listeners.push(callback);
  1199. };
  1200. EventEmitter.removeListener =
  1201. EventEmitter.removeEventListener = function(eventName, callback) {
  1202. this._eventRegistry = this._eventRegistry || {};
  1203. var listeners = this._eventRegistry[eventName];
  1204. if (!listeners)
  1205. return;
  1206. var index = listeners.indexOf(callback);
  1207. if (index !== -1)
  1208. listeners.splice(index, 1);
  1209. };
  1210. EventEmitter.removeAllListeners = function(eventName) {
  1211. if (this._eventRegistry) this._eventRegistry[eventName] = [];
  1212. };
  1213. exports.EventEmitter = EventEmitter;
  1214. });
  1215. define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
  1216. exports.inherits = (function() {
  1217. var tempCtor = function() {};
  1218. return function(ctor, superCtor) {
  1219. tempCtor.prototype = superCtor.prototype;
  1220. ctor.super_ = superCtor.prototype;
  1221. ctor.prototype = new tempCtor();
  1222. ctor.prototype.constructor = ctor;
  1223. };
  1224. }());
  1225. exports.mixin = function(obj, mixin) {
  1226. for (var key in mixin) {
  1227. obj[key] = mixin[key];
  1228. }
  1229. };
  1230. exports.implement = function(proto, mixin) {
  1231. exports.mixin(proto, mixin);
  1232. };
  1233. });
  1234. define('ace/mode/javascript_worker', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/worker/mirror', 'ace/worker/jshint', 'ace/narcissus/parser'], function(require, exports, module) {
  1235. var oop = require("../lib/oop");
  1236. var Mirror = require("../worker/mirror").Mirror;
  1237. var lint = require("../worker/jshint").JSHINT;
  1238. var parser = require("../narcissus/parser");
  1239. var JavaScriptWorker = exports.JavaScriptWorker = function(sender) {
  1240. Mirror.call(this, sender);
  1241. this.setTimeout(500);
  1242. };
  1243. oop.inherits(JavaScriptWorker, Mirror);
  1244. (function() {
  1245. this.onUpdate = function() {
  1246. var value = this.doc.getValue();
  1247. value = value.replace(/^#!.*\n/, "\n");
  1248. // var start = new Date();
  1249. try {
  1250. parser.parse(value);
  1251. } catch(e) {
  1252. // console.log("narcissus")
  1253. // console.log(e);
  1254. var chunks = e.message.split(":")
  1255. var message = chunks.pop().trim();
  1256. var lineNumber = parseInt(chunks.pop().trim()) - 1;
  1257. this.sender.emit("narcissus", {
  1258. row: lineNumber,
  1259. column: null, // TODO convert e.cursor
  1260. text: message,
  1261. type: "error"
  1262. });
  1263. return;
  1264. } finally {
  1265. // console.log("parse time: " + (new Date() - start));
  1266. }
  1267. // var start = new Date();
  1268. // console.log("jslint")
  1269. lint(value, {undef: false, onevar: false, passfail: false});
  1270. this.sender.emit("jslint", lint.errors);
  1271. // console.log("lint time: " + (new Date() - start));
  1272. }
  1273. }).call(JavaScriptWorker.prototype);
  1274. });
  1275. define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
  1276. var Document = require("../document").Document;
  1277. var lang = require("../lib/lang");
  1278. var Mirror = exports.Mirror = function(sender) {
  1279. this.sender = sender;
  1280. var doc = this.doc = new Document("");
  1281. var deferredUpdate = this.deferredUpdate = lang.deferredCall(this.onUpdate.bind(this));
  1282. var _self = this;
  1283. sender.on("change", function(e) {
  1284. doc.applyDeltas([e.data]);
  1285. deferredUpdate.schedule(_self.$timeout);
  1286. });
  1287. };
  1288. (function() {
  1289. this.$timeout = 500;
  1290. this.setTimeout = function(timeout) {
  1291. this.$timeout = timeout;
  1292. };
  1293. this.setValue = function(value) {
  1294. this.doc.setValue(value);
  1295. this.deferredUpdate.schedule(this.$timeout);
  1296. };
  1297. this.getValue = function(callbackId) {
  1298. this.sender.callback(this.doc.getValue(), callbackId);
  1299. };
  1300. this.onUpdate = function() {
  1301. // abstract method
  1302. };
  1303. }).call(Mirror.prototype);
  1304. });
  1305. define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
  1306. var oop = require("./lib/oop");
  1307. var EventEmitter = require("./lib/event_emitter").EventEmitter;
  1308. var Range = require("./range").Range;
  1309. var Anchor = require("./anchor").Anchor;
  1310. /**
  1311. * new Document([text])
  1312. * - text (String | Array): The starting text
  1313. *
  1314. * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.
  1315. *
  1316. **/
  1317. var Document = function(text) {
  1318. this.$lines = [];
  1319. // There has to be one line at least in the document. If you pass an empty
  1320. // string to the insert function, nothing will happen. Workaround.
  1321. if (text.length == 0) {
  1322. this.$lines = [""];
  1323. } else if (Array.isArray(text)) {
  1324. this.insertLines(0, text);
  1325. } else {
  1326. this.insert({row: 0, column:0}, text);
  1327. }
  1328. };
  1329. (function() {
  1330. oop.implement(this, EventEmitter);
  1331. this.setValue = function(text) {
  1332. var len = this.getLength();
  1333. this.remove(new Range(0, 0, len, this.getLine(len-1).length));
  1334. this.insert({row: 0, column:0}, text);
  1335. };
  1336. this.getValue = function() {
  1337. return this.getAllLines().join(this.getNewLineCharacter());
  1338. };
  1339. this.createAnchor = function(row, column) {
  1340. return new Anchor(this, row, column);
  1341. };
  1342. // check for IE split bug
  1343. if ("aaa".split(/a/).length == 0)
  1344. this.$split = function(text) {
  1345. return text.replace(/\r\n|\r/g, "\n").split("\n");
  1346. }
  1347. else
  1348. this.$split = function(text) {
  1349. return text.split(/\r\n|\r|\n/);
  1350. };
  1351. this.$detectNewLine = function(text) {
  1352. var match = text.match(/^.*?(\r\n|\r|\n)/m);
  1353. if (match) {
  1354. this.$autoNewLine = match[1];
  1355. } else {
  1356. this.$autoNewLine = "\n";
  1357. }
  1358. };
  1359. this.getNewLineCharacter = function() {
  1360. switch (this.$newLineMode) {
  1361. case "windows":
  1362. return "\r\n";
  1363. case "unix":
  1364. return "\n";
  1365. case "auto":
  1366. return this.$autoNewLine;
  1367. }
  1368. };
  1369. this.$autoNewLine = "\n";
  1370. this.$newLineMode = "auto";
  1371. this.setNewLineMode = function(newLineMode) {
  1372. if (this.$newLineMode === newLineMode)
  1373. return;
  1374. this.$newLineMode = newLineMode;
  1375. };
  1376. this.getNewLineMode = function() {
  1377. return this.$newLineMode;
  1378. };
  1379. this.isNewLine = function(text) {
  1380. return (text == "\r\n" || text == "\r" || text == "\n");
  1381. };
  1382. this.getLine = function(row) {
  1383. return this.$lines[row] || "";
  1384. };
  1385. this.getLines = function(firstRow, lastRow) {
  1386. return this.$lines.slice(firstRow, lastRow + 1);
  1387. };
  1388. this.getAllLines = function() {
  1389. return this.getLines(0, this.getLength());
  1390. };
  1391. this.getLength = function() {
  1392. return this.$lines.length;
  1393. };
  1394. this.getTextRange = function(range) {
  1395. if (range.start.row == range.end.row) {
  1396. return this.$lines[range.start.row].substring(range.start.column,
  1397. range.end.column);
  1398. }
  1399. else {
  1400. var lines = this.getLines(range.start.row+1, range.end.row-1);
  1401. lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
  1402. lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
  1403. return lines.join(this.getNewLineCharacter());
  1404. }
  1405. };
  1406. this.$clipPosition = function(position) {
  1407. var length = this.getLength();
  1408. if (position.row >= length) {
  1409. position.row = Math.max(0, length - 1);
  1410. position.column = this.getLine(length-1).length;
  1411. }
  1412. return position;
  1413. };
  1414. this.insert = function(position, text) {
  1415. if (!text || text.length === 0)
  1416. return position;
  1417. position = this.$clipPosition(position);
  1418. // only detect new lines if the document has no line break yet
  1419. if (this.getLength() <= 1)
  1420. this.$detectNewLine(text);
  1421. var lines = this.$split(text);
  1422. var firstLine = lines.splice(0, 1)[0];
  1423. var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0];
  1424. position = this.insertInLine(position, firstLine);
  1425. if (lastLine !== null) {
  1426. position = this.insertNewLine(position); // terminate first line
  1427. position = this.insertLines(position.row, lines);
  1428. position = this.insertInLine(position, lastLine || "");
  1429. }
  1430. return position;
  1431. };
  1432. this.insertLines = function(row, lines) {
  1433. if (lines.length == 0)
  1434. return {row: row, column: 0};
  1435. // apply doesn't work for big arrays (smallest threshold is on safari 0xFFFF)
  1436. // to circumvent that we have to break huge inserts into smaller chunks here
  1437. if (lines.length > 0xFFFF) {
  1438. var end = this.insertLines(row, lines.slice(0xFFFF));
  1439. lines = lines.slice(0, 0xFFFF);
  1440. }
  1441. var args = [row, 0];
  1442. args.push.apply(args, lines);
  1443. this.$lines.splice.apply(this.$lines, args);
  1444. var range = new Range(row, 0, row + lines.length, 0);
  1445. var delta = {
  1446. action: "insertLines",
  1447. range: range,
  1448. lines: lines
  1449. };
  1450. this._emit("change", { data: delta });
  1451. return end || range.end;
  1452. };
  1453. this.insertNewLine = function(position) {
  1454. position = this.$clipPosition(position);
  1455. var line = this.$lines[position.row] || "";
  1456. this.$lines[position.row] = line.substring(0, position.column);
  1457. this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
  1458. var end = {
  1459. row : position.row + 1,
  1460. column : 0
  1461. };
  1462. var delta = {
  1463. action: "insertText",
  1464. range: Range.fromPoints(position, end),
  1465. text: this.getNewLineCharacter()
  1466. };
  1467. this._emit("change", { data: delta });
  1468. return end;
  1469. };
  1470. this.insertInLine = function(position, text) {
  1471. if (text.length == 0)
  1472. return position;
  1473. var line = this.$lines[position.row] || "";
  1474. this.$lines[position.row] = line.substring(0, position.column) + text
  1475. + line.substring(position.column);
  1476. var end = {
  1477. row : position.row,
  1478. column : position.column + text.length
  1479. };
  1480. var delta = {
  1481. action: "insertText",
  1482. range: Range.fromPoints(position, end),
  1483. text: text
  1484. };
  1485. this._emit("change", { data: delta });
  1486. return end;
  1487. };
  1488. this.remove = function(range) {
  1489. // clip to document
  1490. range.start = this.$clipPosition(range.start);
  1491. range.end = this.$clipPosition(range.end);
  1492. if (range.isEmpty())
  1493. return range.start;
  1494. var firstRow = range.start.row;
  1495. var lastRow = range.end.row;
  1496. if (range.isMultiLine()) {
  1497. var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1;
  1498. var lastFullRow = lastRow - 1;
  1499. if (range.end.column > 0)
  1500. this.removeInLine(lastRow, 0, range.end.column);
  1501. if (lastFullRow >= firstFullRow)
  1502. this.removeLines(firstFullRow, lastFullRow);
  1503. if (firstFullRow != firstRow) {
  1504. this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
  1505. this.removeNewLine(range.start.row);
  1506. }
  1507. }
  1508. else {
  1509. this.removeInLine(firstRow, range.start.column, range.end.column);
  1510. }
  1511. return range.start;
  1512. };
  1513. this.removeInLine = function(row, startColumn, endColumn) {
  1514. if (startColumn == endColumn)
  1515. return;
  1516. var range = new Range(row, startColumn, row, endColumn);
  1517. var line = this.getLine(row);
  1518. var removed = line.substring(startColumn, endColumn);
  1519. var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
  1520. this.$lines.splice(row, 1, newLine);
  1521. var delta = {
  1522. action: "removeText",
  1523. range: range,
  1524. text: removed
  1525. };
  1526. this._emit("change", { data: delta });
  1527. return range.start;
  1528. };
  1529. this.removeLines = function(firstRow, lastRow) {
  1530. var range = new Range(firstRow, 0, lastRow + 1, 0);
  1531. var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
  1532. var delta = {
  1533. action: "removeLines",
  1534. range: range,
  1535. nl: this.getNewLineCharacter(),
  1536. lines: removed
  1537. };
  1538. this._emit("change", { data: delta });
  1539. return removed;
  1540. };
  1541. this.removeNewLine = function(row) {
  1542. var firstLine = this.getLine(row);
  1543. var secondLine = this.getLine(row+1);
  1544. var range = new Range(row, firstLine.length, row+1, 0);
  1545. var line = firstLine + secondLine;
  1546. this.$lines.splice(row, 2, line);
  1547. var delta = {
  1548. action: "removeText",
  1549. range: range,
  1550. text: this.getNewLineCharacter()
  1551. };
  1552. this._emit("change", { data: delta });
  1553. };
  1554. this.replace = function(range, text) {
  1555. if (text.length == 0 && range.isEmpty())
  1556. return range.start;
  1557. // Shortcut: If the text we want to insert is the same as it is already
  1558. // in the document, we don't have to replace anything.
  1559. if (text == this.getTextRange(range))
  1560. return range.end;
  1561. this.remove(range);
  1562. if (text) {
  1563. var end = this.insert(range.start, text);
  1564. }
  1565. else {
  1566. end = range.start;
  1567. }
  1568. return end;
  1569. };
  1570. this.applyDeltas = function(deltas) {
  1571. for (var i=0; i<deltas.length; i++) {
  1572. var delta = deltas[i];
  1573. var range = Range.fromPoints(delta.range.start, delta.range.end);
  1574. if (delta.action == "insertLines")
  1575. this.insertLines(range.start.row, delta.lines);
  1576. else if (delta.action == "insertText")
  1577. this.insert(range.start, delta.text);
  1578. else if (delta.action == "removeLines")
  1579. this.removeLines(range.start.row, range.end.row - 1);
  1580. else if (delta.action == "removeText")
  1581. this.remove(range);
  1582. }
  1583. };
  1584. this.revertDeltas = function(deltas) {
  1585. for (var i=deltas.length-1; i>=0; i--) {
  1586. var delta = deltas[i];
  1587. var range = Range.fromPoints(delta.range.start, delta.range.end);
  1588. if (delta.action == "insertLines")
  1589. this.removeLines(range.start.row, range.end.row - 1);
  1590. else if (delta.action == "insertText")
  1591. this.remove(range);
  1592. else if (delta.action == "removeLines")
  1593. this.insertLines(range.start.row, delta.lines);
  1594. else if (delta.action == "removeText")
  1595. this.insert(range.start, delta.text);
  1596. }
  1597. };
  1598. }).call(Document.prototype);
  1599. exports.Document = Document;
  1600. });
  1601. define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
  1602. /**
  1603. * class Range
  1604. *
  1605. * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
  1606. *
  1607. **/
  1608. /**
  1609. * new Range(startRow, startColumn, endRow, endColumn)
  1610. * - startRow (Number): The starting row
  1611. * - startColumn (Number): The starting column
  1612. * - endRow (Number): The ending row
  1613. * - endColumn (Number): The ending column
  1614. *
  1615. * Creates a new `Range` object with the given starting and ending row and column points.
  1616. *
  1617. **/
  1618. var Range = function(startRow, startColumn, endRow, endColumn) {
  1619. this.start = {
  1620. row: startRow,
  1621. column: startColumn
  1622. };
  1623. this.end = {
  1624. row: endRow,
  1625. column: endColumn
  1626. };
  1627. };
  1628. (function() {
  1629. /**
  1630. * Range.isEqual(range) -> Boolean
  1631. * - range (Range): A range to check against
  1632. *
  1633. * Returns `true` if and only if the starting row and column, and ending tow and column, are equivalent to those given by `range`.
  1634. *
  1635. **/
  1636. this.isEqual = function(range) {
  1637. return this.start.row == range.start.row &&
  1638. this.end.row == range.end.row &&
  1639. this.start.column == range.start.column &&
  1640. this.end.column == range.end.column
  1641. };
  1642. this.toString = function() {
  1643. return ("Range: [" + this.start.row + "/" + this.start.column +
  1644. "] -> [" + this.end.row + "/" + this.end.column + "]");
  1645. };
  1646. this.contains = function(row, column) {
  1647. return this.compare(row, column) == 0;
  1648. };
  1649. this.compareRange = function(range) {
  1650. var cmp,
  1651. end = range.end,
  1652. start = range.start;
  1653. cmp = this.compare(end.row, end.column);
  1654. if (cmp == 1) {
  1655. cmp = this.compare(start.row, start.column);
  1656. if (cmp == 1) {
  1657. return 2;
  1658. } else if (cmp == 0) {
  1659. return 1;
  1660. } else {
  1661. return 0;
  1662. }
  1663. } else if (cmp == -1) {
  1664. return -2;
  1665. } else {
  1666. cmp = this.compare(start.row, start.column);
  1667. if (cmp == -1) {
  1668. return -1;
  1669. } else if (cmp == 1) {
  1670. return 42;
  1671. } else {
  1672. return 0;
  1673. }
  1674. }
  1675. }
  1676. /** related to: Range.compare
  1677. * Range.comparePoint(p) -> Number
  1678. * - p (Range): A point to compare with
  1679. * + (Number): This method returns one of the following numbers:<br/>
  1680. * * `0` if the two points are exactly equal<br/>
  1681. * * `-1` if `p.row` is less then the calling range<br/>
  1682. * * `1` if `p.row` is greater than the calling range<br/>
  1683. * <br/>
  1684. * If the starting row of the calling range is equal to `p.row`, and:<br/>
  1685. * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`<br/>
  1686. * * Otherwise, it returns -1<br/>
  1687. *<br/>
  1688. * If the ending row of the calling range is equal to `p.row`, and:<br/>
  1689. * * `p.column` is less than or equal to the calling range's ending column, this returns `0`<br/>
  1690. * * Otherwise, it returns 1<br/>
  1691. *
  1692. * Checks the row and column points of `p` with the row and column points of the calling range.
  1693. *
  1694. *
  1695. *
  1696. **/
  1697. this.comparePoint = function(p) {
  1698. return this.compare(p.row, p.column);
  1699. }
  1700. /** related to: Range.comparePoint
  1701. * Range.containsRange(range) -> Boolean
  1702. * - range (Range): A range to compare with
  1703. *
  1704. * Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
  1705. *
  1706. **/
  1707. this.containsRange = function(range) {
  1708. return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
  1709. }
  1710. /**
  1711. * Range.intersects(range) -> Boolean
  1712. * - range (Range): A range to compare with
  1713. *
  1714. * Returns `true` if passed in `range` intersects with the one calling this method.
  1715. *
  1716. **/
  1717. this.intersects = function(range) {
  1718. var cmp = this.compareRange(range);
  1719. return (cmp == -1 || cmp == 0 || cmp == 1);
  1720. }
  1721. /**
  1722. * Range.isEnd(row, column) -> Boolean
  1723. * - row (Number): A row point to compare with
  1724. * - column (Number): A column point to compare with
  1725. *
  1726. * Returns `true` if the caller's ending row point is the same as `row`, and if the caller's ending column is the same as `column`.
  1727. *
  1728. **/
  1729. this.isEnd = function(row, column) {
  1730. return this.end.row == row && this.end.column == column;
  1731. }
  1732. /**
  1733. * Range.isStart(row, column) -> Boolean
  1734. * - row (Number): A row point to compare with
  1735. * - column (Number): A column point to compare with
  1736. *
  1737. * Returns `true` if the caller's starting row point is the same as `row`, and if the caller's starting column is the same as `column`.
  1738. *
  1739. **/
  1740. this.isStart = function(row, column) {
  1741. return this.start.row == row && this.start.column == column;
  1742. }
  1743. /**
  1744. * Range.setStart(row, column)
  1745. * - row (Number): A row point to set
  1746. * - column (Number): A column point to set
  1747. *
  1748. * Sets the starting row and column for the range.
  1749. *
  1750. **/
  1751. this.setStart = function(row, column) {
  1752. if (typeof row == "object") {
  1753. this.start.column = row.column;
  1754. this.start.row = row.row;
  1755. } else {
  1756. this.start.row = row;
  1757. this.start.column = column;
  1758. }
  1759. }
  1760. /**
  1761. * Range.setEnd(row, column)
  1762. * - row (Number): A row point to set
  1763. * - column (Number): A column point to set
  1764. *
  1765. * Sets the starting row and column for the range.
  1766. *
  1767. **/
  1768. this.setEnd = function(row, column) {
  1769. if (typeof row == "object") {
  1770. this.end.column = row.column;
  1771. this.end.row = row.row;
  1772. } else {
  1773. this.end.row = row;
  1774. this.end.column = column;
  1775. }
  1776. }
  1777. /** related to: Range.compare
  1778. * Range.inside(row, column) -> Boolean
  1779. * - row (Number): A row point to compare with
  1780. * - column (Number): A column point to compare with
  1781. *
  1782. * Returns `true` if the `row` and `column` are within the given range.
  1783. *
  1784. **/
  1785. this.inside = function(row, column) {
  1786. if (this.compare(row, column) == 0) {
  1787. if (this.isEnd(row, column) || this.isStart(row, column)) {
  1788. return false;
  1789. } else {
  1790. return true;
  1791. }
  1792. }
  1793. return false;
  1794. }
  1795. /** related to: Range.compare
  1796. * Range.insideStart(row, column) -> Boolean
  1797. * - row (Number): A row point to compare with
  1798. * - column (Number): A column point to compare with
  1799. *
  1800. * Returns `true` if the `row` and `column` are within the given range's starting points.
  1801. *
  1802. **/
  1803. this.insideStart = function(row, column) {
  1804. if (this.compare(row, column) == 0) {
  1805. if (this.isEnd(row, column)) {
  1806. return false;
  1807. } else {
  1808. return true;
  1809. }
  1810. }
  1811. return false;
  1812. }
  1813. /** related to: Range.compare
  1814. * Range.insideEnd(row, column) -> Boolean
  1815. * - row (Number): A row point to compare with
  1816. * - column (Number): A column point to compare with
  1817. *
  1818. * Returns `true` if the `row` and `column` are within the given range's ending points.
  1819. *
  1820. **/
  1821. this.insideEnd = function(row, column) {
  1822. if (this.compare(row, column) == 0) {
  1823. if (this.isStart(row, column)) {
  1824. return false;
  1825. } else {
  1826. return true;
  1827. }
  1828. }
  1829. return false;
  1830. }
  1831. /**
  1832. * Range.compare(row, column) -> Number
  1833. * - row (Number): A row point to compare with
  1834. * - column (Number): A column point to compare with
  1835. * + (Number): This method returns one of the following numbers:<br/>
  1836. * * `0` if the two points are exactly equal <br/>
  1837. * * `-1` if `p.row` is less then the calling range <br/>
  1838. * * `1` if `p.row` is greater than the calling range <br/>
  1839. * <br/>
  1840. * If the starting row of the calling range is equal to `p.row`, and: <br/>
  1841. * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`<br/>
  1842. * * Otherwise, it returns -1<br/>
  1843. * <br/>
  1844. * If the ending row of the calling range is equal to `p.row`, and: <br/>
  1845. * * `p.column` is less than or equal to the calling range's ending column, this returns `0` <br/>
  1846. * * Otherwise, it returns 1
  1847. *
  1848. * Checks the row and column points with the row and column points of the calling range.
  1849. *
  1850. *
  1851. **/
  1852. this.compare = function(row, column) {
  1853. if (!this.isMultiLine()) {
  1854. if (row === this.start.row) {
  1855. return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
  1856. };
  1857. }
  1858. if (row < this.start.row)
  1859. return -1;
  1860. if (row > this.end.row)
  1861. return 1;
  1862. if (this.start.row === row)
  1863. return column >= this.start.column ? 0 : -1;
  1864. if (this.end.row === row)
  1865. return column <= this.end.column ? 0 : 1;
  1866. return 0;
  1867. };
  1868. this.compareStart = function(row, column) {
  1869. if (this.start.row == row && this.start.column == column) {
  1870. return -1;
  1871. } else {
  1872. return this.compare(row, column);
  1873. }
  1874. }
  1875. /**
  1876. * Range.compareEnd(row, column) -> Number
  1877. * - row (Number): A row point to compare with
  1878. * - column (Number): A column point to compare with
  1879. * + (Number): This method returns one of the following numbers:<br/>
  1880. * * `0` if the two points are exactly equal<br/>
  1881. * * `-1` if `p.row` is less then the calling range<br/>
  1882. * * `1` if `p.row` is greater than the calling range, or if `isEnd` is `true.<br/>
  1883. * <br/>
  1884. * If the starting row of the calling range is equal to `p.row`, and:<br/>
  1885. * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`<br/>
  1886. * * Otherwise, it returns -1<br/>
  1887. *<br/>
  1888. * If the ending row of the calling range is equal to `p.row`, and:<br/>
  1889. * * `p.column` is less than or equal to the calling range's ending column, this returns `0`<br/>
  1890. * * Otherwise, it returns 1
  1891. *
  1892. * Checks the row and column points with the row and column points of the calling range.
  1893. *
  1894. *
  1895. **/
  1896. this.compareEnd = function(row, column) {
  1897. if (this.end.row == row && this.end.column == column) {
  1898. return 1;
  1899. } else {
  1900. return this.compare(row, column);
  1901. }
  1902. }
  1903. /**
  1904. * Range.compareInside(row, column) -> Number
  1905. * - row (Number): A row point to compare with
  1906. * - column (Number): A column point to compare with
  1907. * + (Number): This method returns one of the following numbers:<br/>
  1908. * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`<br/>
  1909. * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`<br/>
  1910. * <br/>
  1911. * Otherwise, it returns the value after calling [[Range.compare `compare()`]].
  1912. *
  1913. * Checks the row and column points with the row and column points of the calling range.
  1914. *
  1915. *
  1916. *
  1917. **/
  1918. this.compareInside = function(row, column) {
  1919. if (this.end.row == row && this.end.column == column) {
  1920. return 1;
  1921. } else if (this.start.row == row && this.start.column == column) {
  1922. return -1;
  1923. } else {
  1924. return this.compare(row, column);
  1925. }
  1926. }
  1927. /**
  1928. * Range.clipRows(firstRow, lastRow) -> Range
  1929. * - firstRow (Number): The starting row
  1930. * - lastRow (Number): The ending row
  1931. *
  1932. * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
  1933. *
  1934. **/
  1935. this.clipRows = function(firstRow, lastRow) {
  1936. if (this.end.row > lastRow) {
  1937. var end = {
  1938. row: lastRow+1,
  1939. column: 0
  1940. };
  1941. }
  1942. if (this.start.row > lastRow) {
  1943. var start = {
  1944. row: lastRow+1,
  1945. column: 0
  1946. };
  1947. }
  1948. if (this.start.row < firstRow) {
  1949. var start = {
  1950. row: firstRow,
  1951. column: 0
  1952. };
  1953. }
  1954. if (this.end.row < firstRow) {
  1955. var end = {
  1956. row: firstRow,
  1957. column: 0
  1958. };
  1959. }
  1960. return Range.fromPoints(start || this.start, end || this.end);
  1961. };
  1962. this.extend = function(row, column) {
  1963. var cmp = this.compare(row, column);
  1964. if (cmp == 0)
  1965. return this;
  1966. else if (cmp == -1)
  1967. var start = {row: row, column: column};
  1968. else
  1969. var end = {row: row, column: column};
  1970. return Range.fromPoints(start || this.start, end || this.end);
  1971. };
  1972. this.isEmpty = function() {
  1973. return (this.start.row == this.end.row && this.start.column == this.end.column);
  1974. };
  1975. this.isMultiLine = function() {
  1976. return (this.start.row !== this.end.row);
  1977. };
  1978. this.clone = function() {
  1979. return Range.fromPoints(this.start, this.end);
  1980. };
  1981. this.collapseRows = function() {
  1982. if (this.end.column == 0)
  1983. return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
  1984. else
  1985. return new Range(this.start.row, 0, this.end.row, 0)
  1986. };
  1987. this.toScreenRange = function(session) {
  1988. var screenPosStart =
  1989. session.documentToScreenPosition(this.start);
  1990. var screenPosEnd =
  1991. session.documentToScreenPosition(this.end);
  1992. return new Range(
  1993. screenPosStart.row, screenPosStart.column,
  1994. screenPosEnd.row, screenPosEnd.column
  1995. );
  1996. };
  1997. }).call(Range.prototype);
  1998. Range.fromPoints = function(start, end) {
  1999. return new Range(start.row, start.column, end.row, end.column);
  2000. };
  2001. exports.Range = Range;
  2002. });
  2003. define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
  2004. var oop = require("./lib/oop");
  2005. var EventEmitter = require("./lib/event_emitter").EventEmitter;
  2006. /**
  2007. * new Anchor(doc, row, column)
  2008. * - doc (Document): The document to associate with the anchor
  2009. * - row (Number): The starting row position
  2010. * - column (Number): The starting column position
  2011. *
  2012. * Creates a new `Anchor` and associates it with a document.
  2013. *
  2014. **/
  2015. var Anchor = exports.Anchor = function(doc, row, column) {
  2016. this.document = doc;
  2017. if (typeof column == "undefined")
  2018. this.setPosition(row.row, row.column);
  2019. else
  2020. this.setPosition(row, column);
  2021. this.$onChange = this.onChange.bind(this);
  2022. doc.on("change", this.$onChange);
  2023. };
  2024. (function() {
  2025. oop.implement(this, EventEmitter);
  2026. this.getPosition = function() {
  2027. return this.$clipPositionToDocument(this.row, this.column);
  2028. };
  2029. this.getDocument = function() {
  2030. return this.document;
  2031. };
  2032. this.onChange = function(e) {
  2033. var delta = e.data;
  2034. var range = delta.range;
  2035. if (range.start.row == range.end.row && range.start.row != this.row)
  2036. return;
  2037. if (range.start.row > this.row)
  2038. return;
  2039. if (range.start.row == this.row && range.start.column > this.column)
  2040. return;
  2041. var row = this.row;
  2042. var column = this.column;
  2043. if (delta.action === "insertText") {
  2044. if (range.start.row === row && range.start.column <= column) {
  2045. if (range.start.row === range.end.row) {
  2046. column += range.end.column - range.start.column;
  2047. }
  2048. else {
  2049. column -= range.start.column;
  2050. row += range.end.row - range.start.row;
  2051. }
  2052. }
  2053. else if (range.start.row !== range.end.row && range.start.row < row) {
  2054. row += range.end.row - range.start.row;
  2055. }
  2056. } else if (delta.action === "insertLines") {
  2057. if (range.start.row <= row) {
  2058. row += range.end.row - range.start.row;
  2059. }
  2060. }
  2061. else if (delta.action == "removeText") {
  2062. if (range.start.row == row && range.start.column < column) {
  2063. if (range.end.column >= column)
  2064. column = range.start.column;
  2065. else
  2066. column = Math.max(0, column - (range.end.column - range.start.column));
  2067. } else if (range.start.row !== range.end.row && range.start.row < row) {
  2068. if (range.end.row == row) {
  2069. column = Math.max(0, column - range.end.column) + range.start.column;
  2070. }
  2071. row -= (range.end.row - range.start.row);
  2072. }
  2073. else if (range.end.row == row) {
  2074. row -= range.end.row - range.start.row;
  2075. column = Math.max(0, column - range.end.column) + range.start.column;
  2076. }
  2077. } else if (delta.action == "removeLines") {
  2078. if (range.start.row <= row) {
  2079. if (range.end.row <= row)
  2080. row -= range.end.row - range.start.row;
  2081. else {
  2082. row = range.start.row;
  2083. column = 0;
  2084. }
  2085. }
  2086. }
  2087. this.setPosition(row, column, true);
  2088. };
  2089. this.setPosition = function(row, column, noClip) {
  2090. var pos;
  2091. if (noClip) {
  2092. pos = {
  2093. row: row,
  2094. column: column
  2095. };
  2096. }
  2097. else {
  2098. pos = this.$clipPositionToDocument(row, column);
  2099. }
  2100. if (this.row == pos.row && this.column == pos.column)
  2101. return;
  2102. var old = {
  2103. row: this.row,
  2104. column: this.column
  2105. };
  2106. this.row = pos.row;
  2107. this.column = pos.column;
  2108. this._emit("change", {
  2109. old: old,
  2110. value: pos
  2111. });
  2112. };
  2113. this.detach = function() {
  2114. this.document.removeEventListener("change", this.$onChange);
  2115. };
  2116. this.$clipPositionToDocument = function(row, column) {
  2117. var pos = {};
  2118. if (row >= this.document.getLength()) {
  2119. pos.row = Math.max(0, this.document.getLength() - 1);
  2120. pos.column = this.document.getLine(pos.row).length;
  2121. }
  2122. else if (row < 0) {
  2123. pos.row = 0;
  2124. pos.column = 0;
  2125. }
  2126. else {
  2127. pos.row = row;
  2128. pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
  2129. }
  2130. if (column < 0)
  2131. pos.column = 0;
  2132. return pos;
  2133. };
  2134. }).call(Anchor.prototype);
  2135. });
  2136. define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
  2137. exports.stringReverse = function(string) {
  2138. return string.split("").reverse().join("");
  2139. };
  2140. exports.stringRepeat = function (string, count) {
  2141. return new Array(count + 1).join(string);
  2142. };
  2143. var trimBeginRegexp = /^\s\s*/;
  2144. var trimEndRegexp = /\s\s*$/;
  2145. exports.stringTrimLeft = function (string) {
  2146. return string.replace(trimBeginRegexp, '');
  2147. };
  2148. exports.stringTrimRight = function (string) {
  2149. return string.replace(trimEndRegexp, '');
  2150. };
  2151. exports.copyObject = function(obj) {
  2152. var copy = {};
  2153. for (var key in obj) {
  2154. copy[key] = obj[key];
  2155. }
  2156. return copy;
  2157. };
  2158. exports.copyArray = function(array){
  2159. var copy = [];
  2160. for (var i=0, l=array.length; i<l; i++) {
  2161. if (array[i] && typeof array[i] == "object")
  2162. copy[i] = this.copyObject( array[i] );
  2163. else
  2164. copy[i] = array[i];
  2165. }
  2166. return copy;
  2167. };
  2168. exports.deepCopy = function (obj) {
  2169. if (typeof obj != "object") {
  2170. return obj;
  2171. }
  2172. var copy = obj.constructor();
  2173. for (var key in obj) {
  2174. if (typeof obj[key] == "object") {
  2175. copy[key] = this.deepCopy(obj[key]);
  2176. } else {
  2177. copy[key] = obj[key];
  2178. }
  2179. }
  2180. return copy;
  2181. };
  2182. exports.arrayToMap = function(arr) {
  2183. var map = {};
  2184. for (var i=0; i<arr.length; i++) {
  2185. map[arr[i]] = 1;
  2186. }
  2187. return map;
  2188. };
  2189. exports.arrayRemove = function(array, value) {
  2190. for (var i = 0; i <= array.length; i++) {
  2191. if (value === array[i]) {
  2192. array.splice(i, 1);
  2193. }
  2194. }
  2195. };
  2196. exports.escapeRegExp = function(str) {
  2197. return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
  2198. };
  2199. exports.getMatchOffsets = function(string, regExp) {
  2200. var matches = [];
  2201. string.replace(regExp, function(str) {
  2202. matches.push({
  2203. offset: arguments[arguments.length-2],
  2204. length: str.length
  2205. });
  2206. });
  2207. return matches;
  2208. };
  2209. exports.deferredCall = function(fcn) {
  2210. var timer = null;
  2211. var callback = function() {
  2212. timer = null;
  2213. fcn();
  2214. };
  2215. var deferred = function(timeout) {
  2216. deferred.cancel();
  2217. timer = setTimeout(callback, timeout || 0);
  2218. return deferred;
  2219. };
  2220. deferred.schedule = deferred;
  2221. deferred.call = function() {
  2222. this.cancel();
  2223. fcn();
  2224. return deferred;
  2225. };
  2226. deferred.cancel = function() {
  2227. clearTimeout(timer);
  2228. timer = null;
  2229. return deferred;
  2230. };
  2231. return deferred;
  2232. };
  2233. });
  2234. define('ace/worker/jshint', ['require', 'exports', 'module' ], function(require, exports, module) {
  2235. /*!
  2236. * JSHint, by JSHint Community.
  2237. *
  2238. * Licensed under the same slightly modified MIT license that JSLint is.
  2239. * It stops evil-doers everywhere.
  2240. *
  2241. * JSHint is a derivative work of JSLint:
  2242. *
  2243. * Copyright (c) 2002 Douglas Crockford (www.JSLint.com)
  2244. *
  2245. * Permission is hereby granted, free of charge, to any person obtaining
  2246. * a copy of this software and associated documentation files (the "Software"),
  2247. * to deal in the Software without restriction, including without limitation
  2248. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  2249. * and/or sell copies of the Software, and to permit persons to whom
  2250. * the Software is furnished to do so, subject to the following conditions:
  2251. *
  2252. * The above copyright notice and this permission notice shall be included
  2253. * in all copies or substantial portions of the Software.
  2254. *
  2255. * The Software shall be used for Good, not Evil.
  2256. *
  2257. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2258. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2259. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2260. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2261. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  2262. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  2263. * DEALINGS IN THE SOFTWARE.
  2264. *
  2265. * JSHint was forked from 2010-12-16 edition of JSLint.
  2266. *
  2267. */
  2268. /*
  2269. JSHINT is a global function. It takes two parameters.
  2270. var myResult = JSHINT(source, option);
  2271. The first parameter is either a string or an array of strings. If it is a
  2272. string, it will be split on '\n' or '\r'. If it is an array of strings, it
  2273. is assumed that each string represents one line. The source can be a
  2274. JavaScript text or a JSON text.
  2275. The second parameter is an optional object of options which control the
  2276. operation of JSHINT. Most of the options are booleans: They are all
  2277. optional and have a default value of false. One of the options, predef,
  2278. can be an array of names, which will be used to declare global variables,
  2279. or an object whose keys are used as global names, with a boolean value
  2280. that determines if they are assignable.
  2281. If it checks out, JSHINT returns true. Otherwise, it returns false.
  2282. If false, you can inspect JSHINT.errors to find out the problems.
  2283. JSHINT.errors is an array of objects containing these members:
  2284. {
  2285. line : The line (relative to 0) at which the lint was found
  2286. character : The character (relative to 0) at which the lint was found
  2287. reason : The problem
  2288. evidence : The text line in which the problem occurred
  2289. raw : The raw message before the details were inserted
  2290. a : The first detail
  2291. b : The second detail
  2292. c : The third detail
  2293. d : The fourth detail
  2294. }
  2295. If a fatal error was found, a null will be the last element of the
  2296. JSHINT.errors array.
  2297. You can request a Function Report, which shows all of the functions
  2298. and the parameters and vars that they use. This can be used to find
  2299. implied global variables and other problems. The report is in HTML and
  2300. can be inserted in an HTML <body>.
  2301. var myReport = JSHINT.report(limited);
  2302. If limited is true, then the report will be limited to only errors.
  2303. You can request a data structure which contains JSHint's results.
  2304. var myData = JSHINT.data();
  2305. It returns a structure with this form:
  2306. {
  2307. errors: [
  2308. {
  2309. line: NUMBER,
  2310. character: NUMBER,
  2311. reason: STRING,
  2312. evidence: STRING
  2313. }
  2314. ],
  2315. functions: [
  2316. name: STRING,
  2317. line: NUMBER,
  2318. last: NUMBER,
  2319. param: [
  2320. STRING
  2321. ],
  2322. closure: [
  2323. STRING
  2324. ],
  2325. var: [
  2326. STRING
  2327. ],
  2328. exception: [
  2329. STRING
  2330. ],
  2331. outer: [
  2332. STRING
  2333. ],
  2334. unused: [
  2335. STRING
  2336. ],
  2337. global: [
  2338. STRING
  2339. ],
  2340. label: [
  2341. STRING
  2342. ]
  2343. ],
  2344. globals: [
  2345. STRING
  2346. ],
  2347. member: {
  2348. STRING: NUMBER
  2349. },
  2350. unused: [
  2351. {
  2352. name: STRING,
  2353. line: NUMBER
  2354. }
  2355. ],
  2356. implieds: [
  2357. {
  2358. name: STRING,
  2359. line: NUMBER
  2360. }
  2361. ],
  2362. urls: [
  2363. STRING
  2364. ],
  2365. json: BOOLEAN
  2366. }
  2367. Empty arrays will not be included.
  2368. */
  2369. /*jshint
  2370. evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true,
  2371. undef: true, maxlen: 100, indent:4
  2372. */
  2373. /*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)",
  2374. "(breakage)", "(context)", "(error)", "(global)", "(identifier)", "(last)",
  2375. "(line)", "(loopage)", "(name)", "(onevar)", "(params)", "(scope)",
  2376. "(statement)", "(verb)", "*", "+", "++", "-", "--", "\/", "<", "<=", "==",
  2377. "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax,
  2378. __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Audio,
  2379. Autocompleter, Assets, Boolean, Builder, Buffer, Browser, COM, CScript, Canvas,
  2380. CustomAnimation, Class, Control, Chain, Color, Cookie, Core, DataView, Date,
  2381. Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMReady, DOMParser, Drag,
  2382. E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event,
  2383. Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form,
  2384. FormField, Frame, FormData, Function, Fx, GetObject, Group, Hash, HotKey,
  2385. HTMLElement, HTMLAnchorElement, HTMLBaseElement, HTMLBlockquoteElement,
  2386. HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLCanvasElement, HTMLDirectoryElement,
  2387. HTMLDivElement, HTMLDListElement, HTMLFieldSetElement,
  2388. HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement,
  2389. HTMLHeadElement, HTMLHeadingElement, HTMLHRElement, HTMLHtmlElement,
  2390. HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLIsIndexElement,
  2391. HTMLLabelElement, HTMLLayerElement, HTMLLegendElement, HTMLLIElement,
  2392. HTMLLinkElement, HTMLMapElement, HTMLMenuElement, HTMLMetaElement,
  2393. HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement,
  2394. HTMLOptionElement, HTMLParagraphElement, HTMLParamElement, HTMLPreElement,
  2395. HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLStyleElement,
  2396. HtmlTable, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement,
  2397. HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement,
  2398. HTMLTextAreaElement, HTMLTitleElement, HTMLUListElement, HTMLVideoElement,
  2399. Iframe, IframeShim, Image, Int16Array, Int32Array, Int8Array,
  2400. Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E,
  2401. MAX_VALUE, MIN_VALUE, Mask, Math, MenuItem, MessageChannel, MessageEvent, MessagePort,
  2402. MoveAnimation, MooTools, Native, NEGATIVE_INFINITY, Number, Object, ObjectRange, Option,
  2403. Options, OverText, PI, POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype,
  2404. RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation,
  2405. SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion,
  2406. ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller,
  2407. Slick, Slider, Selector, SharedWorker, String, Style, SyntaxError, Sortable, Sortables,
  2408. SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template,
  2409. Timer, Tips, Type, TypeError, Toggle, Try, "use strict", unescape, URI, URIError, URL,
  2410. VBArray, WSH, WScript, XDomainRequest, Web, Window, XMLDOM, XMLHttpRequest, XMLSerializer,
  2411. XPathEvaluator, XPathException, XPathExpression, XPathNamespace, XPathNSResolver, XPathResult,
  2412. "\\", a, addEventListener, address, alert, apply, applicationCache, arguments, arity, asi, atob,
  2413. b, basic, basicToken, bitwise, block, blur, boolOptions, boss, browser, btoa, c, call, callee,
  2414. caller, cases, charAt, charCodeAt, character, clearInterval, clearTimeout,
  2415. close, closed, closure, comment, condition, confirm, console, constructor,
  2416. content, couch, create, css, curly, d, data, datalist, dd, debug, decodeURI,
  2417. decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document,
  2418. dojo, dijit, dojox, define, else, emit, encodeURI, encodeURIComponent,
  2419. entityify, eqeqeq, eqnull, errors, es5, escape, esnext, eval, event, evidence, evil,
  2420. ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus,
  2421. forin, fragment, frames, from, fromCharCode, fud, funcscope, funct, function, functions,
  2422. g, gc, getComputedStyle, getRow, getter, getterToken, GLOBAL, global, globals, globalstrict,
  2423. hasOwnProperty, help, history, i, id, identifier, immed, implieds, importPackage, include,
  2424. indent, indexOf, init, ins, instanceOf, isAlpha, isApplicationRunning, isArray,
  2425. isDigit, isFinite, isNaN, iterator, java, join, jshint,
  2426. JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastsemic, laxbreak, laxcomma,
  2427. latedef, lbp, led, left, length, line, load, loadClass, localStorage, location,
  2428. log, loopfunc, m, match, maxerr, maxlen, member,message, meta, module, moveBy,
  2429. moveTo, mootools, multistr, name, navigator, new, newcap, noarg, node, noempty, nomen,
  2430. nonew, nonstandard, nud, onbeforeunload, onblur, onerror, onevar, onecase, onfocus,
  2431. onload, onresize, onunload, open, openDatabase, openURL, opener, opera, options, outer, param,
  2432. parent, parseFloat, parseInt, passfail, plusplus, predef, print, process, prompt,
  2433. proto, prototype, prototypejs, provides, push, quit, range, raw, reach, reason, regexp,
  2434. readFile, readUrl, regexdash, removeEventListener, replace, report, require,
  2435. reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, respond, rhino, right,
  2436. runCommand, scroll, screen, scripturl, scrollBy, scrollTo, scrollbar, search, seal,
  2437. send, serialize, sessionStorage, setInterval, setTimeout, setter, setterToken, shift, slice,
  2438. smarttabs, sort, spawn, split, stack, status, start, strict, sub, substr, supernew, shadow,
  2439. supplant, sum, sync, test, toLowerCase, toString, toUpperCase, toint32, token, top, trailing,
  2440. type, typeOf, Uint16Array, Uint32Array, Uint8Array, undef, undefs, unused, urls, validthis,
  2441. value, valueOf, var, version, WebSocket, withstmt, white, window, Worker, wsh*/
  2442. /*global exports: false */
  2443. // We build the application inside a function so that we produce only a single
  2444. // global variable. That function will be invoked immediately, and its return
  2445. // value is the JSHINT function itself.
  2446. var JSHINT = (function () {
  2447. var anonname, // The guessed name for anonymous functions.
  2448. // These are operators that should not be used with the ! operator.
  2449. bang = {
  2450. '<' : true,
  2451. '<=' : true,
  2452. '==' : true,
  2453. '===': true,
  2454. '!==': true,
  2455. '!=' : true,
  2456. '>' : true,
  2457. '>=' : true,
  2458. '+' : true,
  2459. '-' : true,
  2460. '*' : true,
  2461. '/' : true,
  2462. '%' : true
  2463. },
  2464. // These are the JSHint boolean options.
  2465. boolOptions = {
  2466. asi : true, // if automatic semicolon insertion should be tolerated
  2467. bitwise : true, // if bitwise operators should not be allowed
  2468. boss : true, // if advanced usage of assignments should be allowed
  2469. browser : true, // if the standard browser globals should be predefined
  2470. couch : true, // if CouchDB globals should be predefined
  2471. curly : true, // if curly braces around all blocks should be required
  2472. debug : true, // if debugger statements should be allowed
  2473. devel : true, // if logging globals should be predefined (console,
  2474. // alert, etc.)
  2475. dojo : true, // if Dojo Toolkit globals should be predefined
  2476. eqeqeq : true, // if === should be required
  2477. eqnull : true, // if == null comparisons should be tolerated
  2478. es5 : true, // if ES5 syntax should be allowed
  2479. esnext : true, // if es.next specific syntax should be allowed
  2480. evil : true, // if eval should be allowed
  2481. expr : true, // if ExpressionStatement should be allowed as Programs
  2482. forin : true, // if for in statements must filter
  2483. funcscope : true, // if only function scope should be used for scope tests
  2484. globalstrict: true, // if global should be allowed (also
  2485. // enables 'strict')
  2486. immed : true, // if immediate invocations must be wrapped in parens
  2487. iterator : true, // if the `__iterator__` property should be allowed
  2488. jquery : true, // if jQuery globals should be predefined
  2489. lastsemic : true, // if semicolons may be ommitted for the trailing
  2490. // statements inside of a one-line blocks.
  2491. latedef : true, // if the use before definition should not be tolerated
  2492. laxbreak : true, // if line breaks should not be checked
  2493. laxcomma : true, // if line breaks should not be checked around commas
  2494. loopfunc : true, // if functions should be allowed to be defined within
  2495. // loops
  2496. mootools : true, // if MooTools globals should be predefined
  2497. multistr : true, // allow multiline strings
  2498. newcap : true, // if constructor names must be capitalized
  2499. noarg : true, // if arguments.caller and arguments.callee should be
  2500. // disallowed
  2501. node : true, // if the Node.js environment globals should be
  2502. // predefined
  2503. noempty : true, // if empty blocks should be disallowed
  2504. nonew : true, // if using `new` for side-effects should be disallowed
  2505. nonstandard : true, // if non-standard (but widely adopted) globals should
  2506. // be predefined
  2507. nomen : true, // if names should be checked
  2508. onevar : true, // if only one var statement per function should be
  2509. // allowed
  2510. onecase : true, // if one case switch statements should be allowed
  2511. passfail : true, // if the scan should stop on first error
  2512. plusplus : true, // if increment/decrement should not be allowed
  2513. proto : true, // if the `__proto__` property should be allowed
  2514. prototypejs : true, // if Prototype and Scriptaculous globals should be
  2515. // predefined
  2516. regexdash : true, // if unescaped first/last dash (-) inside brackets
  2517. // should be tolerated
  2518. regexp : true, // if the . should not be allowed in regexp literals
  2519. rhino : true, // if the Rhino environment globals should be predefined
  2520. undef : true, // if variables should be declared before used
  2521. scripturl : true, // if script-targeted URLs should be tolerated
  2522. shadow : true, // if variable shadowing should be tolerated
  2523. smarttabs : true, // if smarttabs should be tolerated
  2524. // (http://www.emacswiki.org/emacs/SmartTabs)
  2525. strict : true, // require the pragma
  2526. sub : true, // if all forms of subscript notation are tolerated
  2527. supernew : true, // if `new function () { ... };` and `new Object;`
  2528. // should be tolerated
  2529. trailing : true, // if trailing whitespace rules apply
  2530. validthis : true, // if 'this' inside a non-constructor function is valid.
  2531. // This is a function scoped option only.
  2532. withstmt : true, // if with statements should be allowed
  2533. white : true, // if strict whitespace rules apply
  2534. wsh : true // if the Windows Scripting Host environment globals
  2535. // should be predefined
  2536. },
  2537. // These are the JSHint options that can take any value
  2538. // (we use this object to detect invalid options)
  2539. valOptions = {
  2540. maxlen: false,
  2541. indent: false,
  2542. maxerr: false,
  2543. predef: false
  2544. },
  2545. // browser contains a set of global names which are commonly provided by a
  2546. // web browser environment.
  2547. browser = {
  2548. ArrayBuffer : false,
  2549. ArrayBufferView : false,
  2550. Audio : false,
  2551. addEventListener : false,
  2552. applicationCache : false,
  2553. atob : false,
  2554. blur : false,
  2555. btoa : false,
  2556. clearInterval : false,
  2557. clearTimeout : false,
  2558. close : false,
  2559. closed : false,
  2560. DataView : false,
  2561. DOMParser : false,
  2562. defaultStatus : false,
  2563. document : false,
  2564. event : false,
  2565. FileReader : false,
  2566. Float32Array : false,
  2567. Float64Array : false,
  2568. FormData : false,
  2569. focus : false,
  2570. frames : false,
  2571. getComputedStyle : false,
  2572. HTMLElement : false,
  2573. HTMLAnchorElement : false,
  2574. HTMLBaseElement : false,
  2575. HTMLBlockquoteElement : false,
  2576. HTMLBodyElement : false,
  2577. HTMLBRElement : false,
  2578. HTMLButtonElement : false,
  2579. HTMLCanvasElement : false,
  2580. HTMLDirectoryElement : false,
  2581. HTMLDivElement : false,
  2582. HTMLDListElement : false,
  2583. HTMLFieldSetElement : false,
  2584. HTMLFontElement : false,
  2585. HTMLFormElement : false,
  2586. HTMLFrameElement : false,
  2587. HTMLFrameSetElement : false,
  2588. HTMLHeadElement : false,
  2589. HTMLHeadingElement : false,
  2590. HTMLHRElement : false,
  2591. HTMLHtmlElement : false,
  2592. HTMLIFrameElement : false,
  2593. HTMLImageElement : false,
  2594. HTMLInputElement : false,
  2595. HTMLIsIndexElement : false,
  2596. HTMLLabelElement : false,
  2597. HTMLLayerElement : false,
  2598. HTMLLegendElement : false,
  2599. HTMLLIElement : false,
  2600. HTMLLinkElement : false,
  2601. HTMLMapElement : false,
  2602. HTMLMenuElement : false,
  2603. HTMLMetaElement : false,
  2604. HTMLModElement : false,
  2605. HTMLObjectElement : false,
  2606. HTMLOListElement : false,
  2607. HTMLOptGroupElement : false,
  2608. HTMLOptionElement : false,
  2609. HTMLParagraphElement : false,
  2610. HTMLParamElement : false,
  2611. HTMLPreElement : false,
  2612. HTMLQuoteElement : false,
  2613. HTMLScriptElement : false,
  2614. HTMLSelectElement : false,
  2615. HTMLStyleElement : false,
  2616. HTMLTableCaptionElement : false,
  2617. HTMLTableCellElement : false,
  2618. HTMLTableColElement : false,
  2619. HTMLTableElement : false,
  2620. HTMLTableRowElement : false,
  2621. HTMLTableSectionElement : false,
  2622. HTMLTextAreaElement : false,
  2623. HTMLTitleElement : false,
  2624. HTMLUListElement : false,
  2625. HTMLVideoElement : false,
  2626. history : false,
  2627. Int16Array : false,
  2628. Int32Array : false,
  2629. Int8Array : false,
  2630. Image : false,
  2631. length : false,
  2632. localStorage : false,
  2633. location : false,
  2634. MessageChannel : false,
  2635. MessageEvent : false,
  2636. MessagePort : false,
  2637. moveBy : false,
  2638. moveTo : false,
  2639. name : false,
  2640. navigator : false,
  2641. onbeforeunload : true,
  2642. onblur : true,
  2643. onerror : true,
  2644. onfocus : true,
  2645. onload : true,
  2646. onresize : true,
  2647. onunload : true,
  2648. open : false,
  2649. openDatabase : false,
  2650. opener : false,
  2651. Option : false,
  2652. parent : false,
  2653. print : false,
  2654. removeEventListener : false,
  2655. resizeBy : false,
  2656. resizeTo : false,
  2657. screen : false,
  2658. scroll : false,
  2659. scrollBy : false,
  2660. scrollTo : false,
  2661. sessionStorage : false,
  2662. setInterval : false,
  2663. setTimeout : false,
  2664. SharedWorker : false,
  2665. status : false,
  2666. top : false,
  2667. Uint16Array : false,
  2668. Uint32Array : false,
  2669. Uint8Array : false,
  2670. WebSocket : false,
  2671. window : false,
  2672. Worker : false,
  2673. XMLHttpRequest : false,
  2674. XMLSerializer : false,
  2675. XPathEvaluator : false,
  2676. XPathException : false,
  2677. XPathExpression : false,
  2678. XPathNamespace : false,
  2679. XPathNSResolver : false,
  2680. XPathResult : false
  2681. },
  2682. couch = {
  2683. "require" : false,
  2684. respond : false,
  2685. getRow : false,
  2686. emit : false,
  2687. send : false,
  2688. start : false,
  2689. sum : false,
  2690. log : false,
  2691. exports : false,
  2692. module : false,
  2693. provides : false
  2694. },
  2695. devel = {
  2696. alert : false,
  2697. confirm : false,
  2698. console : false,
  2699. Debug : false,
  2700. opera : false,
  2701. prompt : false
  2702. },
  2703. dojo = {
  2704. dojo : false,
  2705. dijit : false,
  2706. dojox : false,
  2707. define : false,
  2708. "require" : false
  2709. },
  2710. escapes = {
  2711. '\b': '\\b',
  2712. '\t': '\\t',
  2713. '\n': '\\n',
  2714. '\f': '\\f',
  2715. '\r': '\\r',
  2716. '"' : '\\"',
  2717. '/' : '\\/',
  2718. '\\': '\\\\'
  2719. },
  2720. funct, // The current function
  2721. functionicity = [
  2722. 'closure', 'exception', 'global', 'label',
  2723. 'outer', 'unused', 'var'
  2724. ],
  2725. functions, // All of the functions
  2726. global, // The global scope
  2727. implied, // Implied globals
  2728. inblock,
  2729. indent,
  2730. jsonmode,
  2731. jquery = {
  2732. '$' : false,
  2733. jQuery : false
  2734. },
  2735. lines,
  2736. lookahead,
  2737. member,
  2738. membersOnly,
  2739. mootools = {
  2740. '$' : false,
  2741. '$$' : false,
  2742. Assets : false,
  2743. Browser : false,
  2744. Chain : false,
  2745. Class : false,
  2746. Color : false,
  2747. Cookie : false,
  2748. Core : false,
  2749. Document : false,
  2750. DomReady : false,
  2751. DOMReady : false,
  2752. Drag : false,
  2753. Element : false,
  2754. Elements : false,
  2755. Event : false,
  2756. Events : false,
  2757. Fx : false,
  2758. Group : false,
  2759. Hash : false,
  2760. HtmlTable : false,
  2761. Iframe : false,
  2762. IframeShim : false,
  2763. InputValidator : false,
  2764. instanceOf : false,
  2765. Keyboard : false,
  2766. Locale : false,
  2767. Mask : false,
  2768. MooTools : false,
  2769. Native : false,
  2770. Options : false,
  2771. OverText : false,
  2772. Request : false,
  2773. Scroller : false,
  2774. Slick : false,
  2775. Slider : false,
  2776. Sortables : false,
  2777. Spinner : false,
  2778. Swiff : false,
  2779. Tips : false,
  2780. Type : false,
  2781. typeOf : false,
  2782. URI : false,
  2783. Window : false
  2784. },
  2785. nexttoken,
  2786. node = {
  2787. __filename : false,
  2788. __dirname : false,
  2789. Buffer : false,
  2790. console : false,
  2791. exports : false,
  2792. GLOBAL : false,
  2793. global : false,
  2794. module : false,
  2795. process : false,
  2796. require : false,
  2797. setTimeout : false,
  2798. clearTimeout : false,
  2799. setInterval : false,
  2800. clearInterval : false
  2801. },
  2802. noreach,
  2803. option,
  2804. predefined, // Global variables defined by option
  2805. prereg,
  2806. prevtoken,
  2807. prototypejs = {
  2808. '$' : false,
  2809. '$$' : false,
  2810. '$A' : false,
  2811. '$F' : false,
  2812. '$H' : false,
  2813. '$R' : false,
  2814. '$break' : false,
  2815. '$continue' : false,
  2816. '$w' : false,
  2817. Abstract : false,
  2818. Ajax : false,
  2819. Class : false,
  2820. Enumerable : false,
  2821. Element : false,
  2822. Event : false,
  2823. Field : false,
  2824. Form : false,
  2825. Hash : false,
  2826. Insertion : false,
  2827. ObjectRange : false,
  2828. PeriodicalExecuter: false,
  2829. Position : false,
  2830. Prototype : false,
  2831. Selector : false,
  2832. Template : false,
  2833. Toggle : false,
  2834. Try : false,
  2835. Autocompleter : false,
  2836. Builder : false,
  2837. Control : false,
  2838. Draggable : false,
  2839. Draggables : false,
  2840. Droppables : false,
  2841. Effect : false,
  2842. Sortable : false,
  2843. SortableObserver : false,
  2844. Sound : false,
  2845. Scriptaculous : false
  2846. },
  2847. rhino = {
  2848. defineClass : false,
  2849. deserialize : false,
  2850. gc : false,
  2851. help : false,
  2852. importPackage: false,
  2853. "java" : false,
  2854. load : false,
  2855. loadClass : false,
  2856. print : false,
  2857. quit : false,
  2858. readFile : false,
  2859. readUrl : false,
  2860. runCommand : false,
  2861. seal : false,
  2862. serialize : false,
  2863. spawn : false,
  2864. sync : false,
  2865. toint32 : false,
  2866. version : false
  2867. },
  2868. scope, // The current scope
  2869. stack,
  2870. // standard contains the global names that are provided by the
  2871. // ECMAScript standard.
  2872. standard = {
  2873. Array : false,
  2874. Boolean : false,
  2875. Date : false,
  2876. decodeURI : false,
  2877. decodeURIComponent : false,
  2878. encodeURI : false,
  2879. encodeURIComponent : false,
  2880. Error : false,
  2881. 'eval' : false,
  2882. EvalError : false,
  2883. Function : false,
  2884. hasOwnProperty : false,
  2885. isFinite : false,
  2886. isNaN : false,
  2887. JSON : false,
  2888. Math : false,
  2889. Number : false,
  2890. Object : false,
  2891. parseInt : false,
  2892. parseFloat : false,
  2893. RangeError : false,
  2894. ReferenceError : false,
  2895. RegExp : false,
  2896. String : false,
  2897. SyntaxError : false,
  2898. TypeError : false,
  2899. URIError : false
  2900. },
  2901. // widely adopted global names that are not part of ECMAScript standard
  2902. nonstandard = {
  2903. escape : false,
  2904. unescape : false
  2905. },
  2906. standard_member = {
  2907. E : true,
  2908. LN2 : true,
  2909. LN10 : true,
  2910. LOG2E : true,
  2911. LOG10E : true,
  2912. MAX_VALUE : true,
  2913. MIN_VALUE : true,
  2914. NEGATIVE_INFINITY : true,
  2915. PI : true,
  2916. POSITIVE_INFINITY : true,
  2917. SQRT1_2 : true,
  2918. SQRT2 : true
  2919. },
  2920. directive,
  2921. syntax = {},
  2922. tab,
  2923. token,
  2924. urls,
  2925. useESNextSyntax,
  2926. warnings,
  2927. wsh = {
  2928. ActiveXObject : true,
  2929. Enumerator : true,
  2930. GetObject : true,
  2931. ScriptEngine : true,
  2932. ScriptEngineBuildVersion : true,
  2933. ScriptEngineMajorVersion : true,
  2934. ScriptEngineMinorVersion : true,
  2935. VBArray : true,
  2936. WSH : true,
  2937. WScript : true,
  2938. XDomainRequest : true
  2939. };
  2940. // Regular expressions. Some of these are stupidly long.
  2941. var ax, cx, tx, nx, nxg, lx, ix, jx, ft;
  2942. (function () {
  2943. /*jshint maxlen:300 */
  2944. // unsafe comment or string
  2945. ax = /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
  2946. // unsafe characters that are silently deleted by one or more browsers
  2947. cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
  2948. // token
  2949. tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/;
  2950. // characters in strings that need escapement
  2951. nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
  2952. nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  2953. // star slash
  2954. lx = /\*\/|\/\*/;
  2955. // identifier
  2956. ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
  2957. // javascript url
  2958. jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
  2959. // catches /* falls through */ comments
  2960. ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/;
  2961. }());
  2962. function F() {} // Used by Object.create
  2963. function is_own(object, name) {
  2964. // The object.hasOwnProperty method fails when the property under consideration
  2965. // is named 'hasOwnProperty'. So we have to use this more convoluted form.
  2966. return Object.prototype.hasOwnProperty.call(object, name);
  2967. }
  2968. function checkOption(name, t) {
  2969. if (valOptions[name] === undefined && boolOptions[name] === undefined) {
  2970. warning("Bad option: '" + name + "'.", t);
  2971. }
  2972. }
  2973. // Provide critical ES5 functions to ES3.
  2974. if (typeof Array.isArray !== 'function') {
  2975. Array.isArray = function (o) {
  2976. return Object.prototype.toString.apply(o) === '[object Array]';
  2977. };
  2978. }
  2979. if (typeof Object.create !== 'function') {
  2980. Object.create = function (o) {
  2981. F.prototype = o;
  2982. return new F();
  2983. };
  2984. }
  2985. if (typeof Object.keys !== 'function') {
  2986. Object.keys = function (o) {
  2987. var a = [], k;
  2988. for (k in o) {
  2989. if (is_own(o, k)) {
  2990. a.push(k);
  2991. }
  2992. }
  2993. return a;
  2994. };
  2995. }
  2996. // Non standard methods
  2997. if (typeof String.prototype.entityify !== 'function') {
  2998. String.prototype.entityify = function () {
  2999. return this
  3000. .replace(/&/g, '&amp;')
  3001. .replace(/</g, '&lt;')
  3002. .replace(/>/g, '&gt;');
  3003. };
  3004. }
  3005. if (typeof String.prototype.isAlpha !== 'function') {
  3006. String.prototype.isAlpha = function () {
  3007. return (this >= 'a' && this <= 'z\uffff') ||
  3008. (this >= 'A' && this <= 'Z\uffff');
  3009. };
  3010. }
  3011. if (typeof String.prototype.isDigit !== 'function') {
  3012. String.prototype.isDigit = function () {
  3013. return (this >= '0' && this <= '9');
  3014. };
  3015. }
  3016. if (typeof String.prototype.supplant !== 'function') {
  3017. String.prototype.supplant = function (o) {
  3018. return this.replace(/\{([^{}]*)\}/g, function (a, b) {
  3019. var r = o[b];
  3020. return typeof r === 'string' || typeof r === 'number' ? r : a;
  3021. });
  3022. };
  3023. }
  3024. if (typeof String.prototype.name !== 'function') {
  3025. String.prototype.name = function () {
  3026. // If the string looks like an identifier, then we can return it as is.
  3027. // If the string contains no control characters, no quote characters, and no
  3028. // backslash characters, then we can simply slap some quotes around it.
  3029. // Otherwise we must also replace the offending characters with safe
  3030. // sequences.
  3031. if (ix.test(this)) {
  3032. return this;
  3033. }
  3034. if (nx.test(this)) {
  3035. return '"' + this.replace(nxg, function (a) {
  3036. var c = escapes[a];
  3037. if (c) {
  3038. return c;
  3039. }
  3040. return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
  3041. }) + '"';
  3042. }
  3043. return '"' + this + '"';
  3044. };
  3045. }
  3046. function combine(t, o) {
  3047. var n;
  3048. for (n in o) {
  3049. if (is_own(o, n)) {
  3050. t[n] = o[n];
  3051. }
  3052. }
  3053. }
  3054. function assume() {
  3055. if (option.couch) {
  3056. combine(predefined, couch);
  3057. }
  3058. if (option.rhino) {
  3059. combine(predefined, rhino);
  3060. }
  3061. if (option.prototypejs) {
  3062. combine(predefined, prototypejs);
  3063. }
  3064. if (option.node) {
  3065. combine(predefined, node);
  3066. option.globalstrict = true;
  3067. }
  3068. if (option.devel) {
  3069. combine(predefined, devel);
  3070. }
  3071. if (option.dojo) {
  3072. combine(predefined, dojo);
  3073. }
  3074. if (option.browser) {
  3075. combine(predefined, browser);
  3076. }
  3077. if (option.nonstandard) {
  3078. combine(predefined, nonstandard);
  3079. }
  3080. if (option.jquery) {
  3081. combine(predefined, jquery);
  3082. }
  3083. if (option.mootools) {
  3084. combine(predefined, mootools);
  3085. }
  3086. if (option.wsh) {
  3087. combine(predefined, wsh);
  3088. }
  3089. if (option.esnext) {
  3090. useESNextSyntax();
  3091. }
  3092. if (option.globalstrict && option.strict !== false) {
  3093. option.strict = true;
  3094. }
  3095. }
  3096. // Produce an error warning.
  3097. function quit(message, line, chr) {
  3098. var percentage = Math.floor((line / lines.length) * 100);
  3099. throw {
  3100. name: 'JSHintError',
  3101. line: line,
  3102. character: chr,
  3103. message: message + " (" + percentage + "% scanned).",
  3104. raw: message
  3105. };
  3106. }
  3107. function isundef(scope, m, t, a) {
  3108. return JSHINT.undefs.push([scope, m, t, a]);
  3109. }
  3110. function warning(m, t, a, b, c, d) {
  3111. var ch, l, w;
  3112. t = t || nexttoken;
  3113. if (t.id === '(end)') { // `~
  3114. t = token;
  3115. }
  3116. l = t.line || 0;
  3117. ch = t.from || 0;
  3118. w = {
  3119. id: '(error)',
  3120. raw: m,
  3121. evidence: lines[l - 1] || '',
  3122. line: l,
  3123. character: ch,
  3124. a: a,
  3125. b: b,
  3126. c: c,
  3127. d: d
  3128. };
  3129. w.reason = m.supplant(w);
  3130. JSHINT.errors.push(w);
  3131. if (option.passfail) {
  3132. quit('Stopping. ', l, ch);
  3133. }
  3134. warnings += 1;
  3135. if (warnings >= option.maxerr) {
  3136. quit("Too many errors.", l, ch);
  3137. }
  3138. return w;
  3139. }
  3140. function warningAt(m, l, ch, a, b, c, d) {
  3141. return warning(m, {
  3142. line: l,
  3143. from: ch
  3144. }, a, b, c, d);
  3145. }
  3146. function error(m, t, a, b, c, d) {
  3147. var w = warning(m, t, a, b, c, d);
  3148. }
  3149. function errorAt(m, l, ch, a, b, c, d) {
  3150. return error(m, {
  3151. line: l,
  3152. from: ch
  3153. }, a, b, c, d);
  3154. }
  3155. // lexical analysis and token construction
  3156. var lex = (function lex() {
  3157. var character, from, line, s;
  3158. // Private lex methods
  3159. function nextLine() {
  3160. var at,
  3161. tw; // trailing whitespace check
  3162. if (line >= lines.length)
  3163. return false;
  3164. character = 1;
  3165. s = lines[line];
  3166. line += 1;
  3167. // If smarttabs option is used check for spaces followed by tabs only.
  3168. // Otherwise check for any occurence of mixed tabs and spaces.
  3169. if (option.smarttabs)
  3170. at = s.search(/ \t/);
  3171. else
  3172. at = s.search(/ \t|\t /);
  3173. if (at >= 0)
  3174. warningAt("Mixed spaces and tabs.", line, at + 1);
  3175. s = s.replace(/\t/g, tab);
  3176. at = s.search(cx);
  3177. if (at >= 0)
  3178. warningAt("Unsafe character.", line, at);
  3179. if (option.maxlen && option.maxlen < s.length)
  3180. warningAt("Line too long.", line, s.length);
  3181. // Check for trailing whitespaces
  3182. tw = option.trailing && s.match(/^(.*?)\s+$/);
  3183. if (tw && !/^\s+$/.test(s)) {
  3184. warningAt("Trailing whitespace.", line, tw[1].length + 1);
  3185. }
  3186. return true;
  3187. }
  3188. // Produce a token object. The token inherits from a syntax symbol.
  3189. function it(type, value) {
  3190. var i, t;
  3191. if (type === '(color)' || type === '(range)') {
  3192. t = {type: type};
  3193. } else if (type === '(punctuator)' ||
  3194. (type === '(identifier)' && is_own(syntax, value))) {
  3195. t = syntax[value] || syntax['(error)'];
  3196. } else {
  3197. t = syntax[type];
  3198. }
  3199. t = Object.create(t);
  3200. if (type === '(string)' || type === '(range)') {
  3201. if (!option.scripturl && jx.test(value)) {
  3202. warningAt("Script URL.", line, from);
  3203. }
  3204. }
  3205. if (type === '(identifier)') {
  3206. t.identifier = true;
  3207. if (value === '__proto__' && !option.proto) {
  3208. warningAt("The '{a}' property is deprecated.",
  3209. line, from, value);
  3210. } else if (value === '__iterator__' && !option.iterator) {
  3211. warningAt("'{a}' is only available in JavaScript 1.7.",
  3212. line, from, value);
  3213. } else if (option.nomen && (value.charAt(0) === '_' ||
  3214. value.charAt(value.length - 1) === '_')) {
  3215. if (!option.node || token.id === '.' ||
  3216. (value !== '__dirname' && value !== '__filename')) {
  3217. warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", value);
  3218. }
  3219. }
  3220. }
  3221. t.value = value;
  3222. t.line = line;
  3223. t.character = character;
  3224. t.from = from;
  3225. i = t.id;
  3226. if (i !== '(endline)') {
  3227. prereg = i &&
  3228. (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
  3229. i === 'return' ||
  3230. i === 'case');
  3231. }
  3232. return t;
  3233. }
  3234. // Public lex methods
  3235. return {
  3236. init: function (source) {
  3237. if (typeof source === 'string') {
  3238. lines = source
  3239. .replace(/\r\n/g, '\n')
  3240. .replace(/\r/g, '\n')
  3241. .split('\n');
  3242. } else {
  3243. lines = source;
  3244. }
  3245. // If the first line is a shebang (#!), make it a blank and move on.
  3246. // Shebangs are used by Node scripts.
  3247. if (lines[0] && lines[0].substr(0, 2) === '#!')
  3248. lines[0] = '';
  3249. line = 0;
  3250. nextLine();
  3251. from = 1;
  3252. },
  3253. range: function (begin, end) {
  3254. var c, value = '';
  3255. from = character;
  3256. if (s.charAt(0) !== begin) {
  3257. errorAt("Expected '{a}' and instead saw '{b}'.",
  3258. line, character, begin, s.charAt(0));
  3259. }
  3260. for (;;) {
  3261. s = s.slice(1);
  3262. character += 1;
  3263. c = s.charAt(0);
  3264. switch (c) {
  3265. case '':
  3266. errorAt("Missing '{a}'.", line, character, c);
  3267. break;
  3268. case end:
  3269. s = s.slice(1);
  3270. character += 1;
  3271. return it('(range)', value);
  3272. case '\\':
  3273. warningAt("Unexpected '{a}'.", line, character, c);
  3274. }
  3275. value += c;
  3276. }
  3277. },
  3278. // token -- this is called by advance to get the next token
  3279. token: function () {
  3280. var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange, n;
  3281. function match(x) {
  3282. var r = x.exec(s), r1;
  3283. if (r) {
  3284. l = r[0].length;
  3285. r1 = r[1];
  3286. c = r1.charAt(0);
  3287. s = s.substr(l);
  3288. from = character + l - r1.length;
  3289. character += l;
  3290. return r1;
  3291. }
  3292. }
  3293. function string(x) {
  3294. var c, j, r = '', allowNewLine = false;
  3295. if (jsonmode && x !== '"') {
  3296. warningAt("Strings must use doublequote.",
  3297. line, character);
  3298. }
  3299. function esc(n) {
  3300. var i = parseInt(s.substr(j + 1, n), 16);
  3301. j += n;
  3302. if (i >= 32 && i <= 126 &&
  3303. i !== 34 && i !== 92 && i !== 39) {
  3304. warningAt("Unnecessary escapement.", line, character);
  3305. }
  3306. character += n;
  3307. c = String.fromCharCode(i);
  3308. }
  3309. j = 0;
  3310. unclosedString: for (;;) {
  3311. while (j >= s.length) {
  3312. j = 0;
  3313. var cl = line, cf = from;
  3314. if (!nextLine()) {
  3315. errorAt("Unclosed string.", cl, cf);
  3316. break unclosedString;
  3317. }
  3318. if (allowNewLine) {
  3319. allowNewLine = false;
  3320. } else {
  3321. warningAt("Unclosed string.", cl, cf);
  3322. }
  3323. }
  3324. c = s.charAt(j);
  3325. if (c === x) {
  3326. character += 1;
  3327. s = s.substr(j + 1);
  3328. return it('(string)', r, x);
  3329. }
  3330. if (c < ' ') {
  3331. if (c === '\n' || c === '\r') {
  3332. break;
  3333. }
  3334. warningAt("Control character in string: {a}.",
  3335. line, character + j, s.slice(0, j));
  3336. } else if (c === '\\') {
  3337. j += 1;
  3338. character += 1;
  3339. c = s.charAt(j);
  3340. n = s.charAt(j + 1);
  3341. switch (c) {
  3342. case '\\':
  3343. case '"':
  3344. case '/':
  3345. break;
  3346. case '\'':
  3347. if (jsonmode) {
  3348. warningAt("Avoid \\'.", line, character);
  3349. }
  3350. break;
  3351. case 'b':
  3352. c = '\b';
  3353. break;
  3354. case 'f':
  3355. c = '\f';
  3356. break;
  3357. case 'n':
  3358. c = '\n';
  3359. break;
  3360. case 'r':
  3361. c = '\r';
  3362. break;
  3363. case 't':
  3364. c = '\t';
  3365. break;
  3366. case '0':
  3367. c = '\0';
  3368. // Octal literals fail in strict mode
  3369. // check if the number is between 00 and 07
  3370. // where 'n' is the token next to 'c'
  3371. if (n >= 0 && n <= 7 && directive["use strict"]) {
  3372. warningAt(
  3373. "Octal literals are not allowed in strict mode.",
  3374. line, character);
  3375. }
  3376. break;
  3377. case 'u':
  3378. esc(4);
  3379. break;
  3380. case 'v':
  3381. if (jsonmode) {
  3382. warningAt("Avoid \\v.", line, character);
  3383. }
  3384. c = '\v';
  3385. break;
  3386. case 'x':
  3387. if (jsonmode) {
  3388. warningAt("Avoid \\x-.", line, character);
  3389. }
  3390. esc(2);
  3391. break;
  3392. case '':
  3393. // last character is escape character
  3394. // always allow new line if escaped, but show
  3395. // warning if option is not set
  3396. allowNewLine = true;
  3397. if (option.multistr) {
  3398. if (jsonmode) {
  3399. warningAt("Avoid EOL escapement.", line, character);
  3400. }
  3401. c = '';
  3402. character -= 1;
  3403. break;
  3404. }
  3405. warningAt("Bad escapement of EOL. Use option multistr if needed.",
  3406. line, character);
  3407. break;
  3408. default:
  3409. warningAt("Bad escapement.", line, character);
  3410. }
  3411. }
  3412. r += c;
  3413. character += 1;
  3414. j += 1;
  3415. }
  3416. }
  3417. for (;;) {
  3418. if (!s) {
  3419. return it(nextLine() ? '(endline)' : '(end)', '');
  3420. }
  3421. t = match(tx);
  3422. if (!t) {
  3423. t = '';
  3424. c = '';
  3425. while (s && s < '!') {
  3426. s = s.substr(1);
  3427. }
  3428. if (s) {
  3429. errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1));
  3430. s = '';
  3431. }
  3432. } else {
  3433. // identifier
  3434. if (c.isAlpha() || c === '_' || c === '$') {
  3435. return it('(identifier)', t);
  3436. }
  3437. // number
  3438. if (c.isDigit()) {
  3439. if (!isFinite(Number(t))) {
  3440. warningAt("Bad number '{a}'.",
  3441. line, character, t);
  3442. }
  3443. if (s.substr(0, 1).isAlpha()) {
  3444. warningAt("Missing space after '{a}'.",
  3445. line, character, t);
  3446. }
  3447. if (c === '0') {
  3448. d = t.substr(1, 1);
  3449. if (d.isDigit()) {
  3450. if (token.id !== '.') {
  3451. warningAt("Don't use extra leading zeros '{a}'.",
  3452. line, character, t);
  3453. }
  3454. } else if (jsonmode && (d === 'x' || d === 'X')) {
  3455. warningAt("Avoid 0x-. '{a}'.",
  3456. line, character, t);
  3457. }
  3458. }
  3459. if (t.substr(t.length - 1) === '.') {
  3460. warningAt(
  3461. "A trailing decimal point can be confused with a dot '{a}'.", line, character, t);
  3462. }
  3463. return it('(number)', t);
  3464. }
  3465. switch (t) {
  3466. // string
  3467. case '"':
  3468. case "'":
  3469. return string(t);
  3470. // // comment
  3471. case '//':
  3472. s = '';
  3473. token.comment = true;
  3474. break;
  3475. // /* comment
  3476. case '/*':
  3477. for (;;) {
  3478. i = s.search(lx);
  3479. if (i >= 0) {
  3480. break;
  3481. }
  3482. if (!nextLine()) {
  3483. errorAt("Unclosed comment.", line, character);
  3484. }
  3485. }
  3486. character += i + 2;
  3487. if (s.substr(i, 1) === '/') {
  3488. errorAt("Nested comment.", line, character);
  3489. }
  3490. s = s.substr(i + 2);
  3491. token.comment = true;
  3492. break;
  3493. // /*members /*jshint /*global
  3494. case '/*members':
  3495. case '/*member':
  3496. case '/*jshint':
  3497. case '/*jslint':
  3498. case '/*global':
  3499. case '*/':
  3500. return {
  3501. value: t,
  3502. type: 'special',
  3503. line: line,
  3504. character: character,
  3505. from: from
  3506. };
  3507. case '':
  3508. break;
  3509. // /
  3510. case '/':
  3511. if (token.id === '/=') {
  3512. errorAt("A regular expression literal can be confused with '/='.",
  3513. line, from);
  3514. }
  3515. if (prereg) {
  3516. depth = 0;
  3517. captures = 0;
  3518. l = 0;
  3519. for (;;) {
  3520. b = true;
  3521. c = s.charAt(l);
  3522. l += 1;
  3523. switch (c) {
  3524. case '':
  3525. errorAt("Unclosed regular expression.", line, from);
  3526. return quit('Stopping.', line, from);
  3527. case '/':
  3528. if (depth > 0) {
  3529. warningAt("{a} unterminated regular expression " +
  3530. "group(s).", line, from + l, depth);
  3531. }
  3532. c = s.substr(0, l - 1);
  3533. q = {
  3534. g: true,
  3535. i: true,
  3536. m: true
  3537. };
  3538. while (q[s.charAt(l)] === true) {
  3539. q[s.charAt(l)] = false;
  3540. l += 1;
  3541. }
  3542. character += l;
  3543. s = s.substr(l);
  3544. q = s.charAt(0);
  3545. if (q === '/' || q === '*') {
  3546. errorAt("Confusing regular expression.",
  3547. line, from);
  3548. }
  3549. return it('(regexp)', c);
  3550. case '\\':
  3551. c = s.charAt(l);
  3552. if (c < ' ') {
  3553. warningAt(
  3554. "Unexpected control character in regular expression.", line, from + l);
  3555. } else if (c === '<') {
  3556. warningAt(
  3557. "Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
  3558. }
  3559. l += 1;
  3560. break;
  3561. case '(':
  3562. depth += 1;
  3563. b = false;
  3564. if (s.charAt(l) === '?') {
  3565. l += 1;
  3566. switch (s.charAt(l)) {
  3567. case ':':
  3568. case '=':
  3569. case '!':
  3570. l += 1;
  3571. break;
  3572. default:
  3573. warningAt(
  3574. "Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
  3575. }
  3576. } else {
  3577. captures += 1;
  3578. }
  3579. break;
  3580. case '|':
  3581. b = false;
  3582. break;
  3583. case ')':
  3584. if (depth === 0) {
  3585. warningAt("Unescaped '{a}'.",
  3586. line, from + l, ')');
  3587. } else {
  3588. depth -= 1;
  3589. }
  3590. break;
  3591. case ' ':
  3592. q = 1;
  3593. while (s.charAt(l) === ' ') {
  3594. l += 1;
  3595. q += 1;
  3596. }
  3597. if (q > 1) {
  3598. warningAt(
  3599. "Spaces are hard to count. Use {{a}}.", line, from + l, q);
  3600. }
  3601. break;
  3602. case '[':
  3603. c = s.charAt(l);
  3604. if (c === '^') {
  3605. l += 1;
  3606. if (option.regexp) {
  3607. warningAt("Insecure '{a}'.",
  3608. line, from + l, c);
  3609. } else if (s.charAt(l) === ']') {
  3610. errorAt("Unescaped '{a}'.",
  3611. line, from + l, '^');
  3612. }
  3613. }
  3614. if (c === ']') {
  3615. warningAt("Empty class.", line,
  3616. from + l - 1);
  3617. }
  3618. isLiteral = false;
  3619. isInRange = false;
  3620. klass: do {
  3621. c = s.charAt(l);
  3622. l += 1;
  3623. switch (c) {
  3624. case '[':
  3625. case '^':
  3626. warningAt("Unescaped '{a}'.",
  3627. line, from + l, c);
  3628. if (isInRange) {
  3629. isInRange = false;
  3630. } else {
  3631. isLiteral = true;
  3632. }
  3633. break;
  3634. case '-':
  3635. if (isLiteral && !isInRange) {
  3636. isLiteral = false;
  3637. isInRange = true;
  3638. } else if (isInRange) {
  3639. isInRange = false;
  3640. } else if (s.charAt(l) === ']') {
  3641. isInRange = true;
  3642. } else {
  3643. if (option.regexdash !== (l === 2 || (l === 3 &&
  3644. s.charAt(1) === '^'))) {
  3645. warningAt("Unescaped '{a}'.",
  3646. line, from + l - 1, '-');
  3647. }
  3648. isLiteral = true;
  3649. }
  3650. break;
  3651. case ']':
  3652. if (isInRange && !option.regexdash) {
  3653. warningAt("Unescaped '{a}'.",
  3654. line, from + l - 1, '-');
  3655. }
  3656. break klass;
  3657. case '\\':
  3658. c = s.charAt(l);
  3659. if (c < ' ') {
  3660. warningAt(
  3661. "Unexpected control character in regular expression.", line, from + l);
  3662. } else if (c === '<') {
  3663. warningAt(
  3664. "Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
  3665. }
  3666. l += 1;
  3667. // \w, \s and \d are never part of a character range
  3668. if (/[wsd]/i.test(c)) {
  3669. if (isInRange) {
  3670. warningAt("Unescaped '{a}'.",
  3671. line, from + l, '-');
  3672. isInRange = false;
  3673. }
  3674. isLiteral = false;
  3675. } else if (isInRange) {
  3676. isInRange = false;
  3677. } else {
  3678. isLiteral = true;
  3679. }
  3680. break;
  3681. case '/':
  3682. warningAt("Unescaped '{a}'.",
  3683. line, from + l - 1, '/');
  3684. if (isInRange) {
  3685. isInRange = false;
  3686. } else {
  3687. isLiteral = true;
  3688. }
  3689. break;
  3690. case '<':
  3691. if (isInRange) {
  3692. isInRange = false;
  3693. } else {
  3694. isLiteral = true;
  3695. }
  3696. break;
  3697. default:
  3698. if (isInRange) {
  3699. isInRange = false;
  3700. } else {
  3701. isLiteral = true;
  3702. }
  3703. }
  3704. } while (c);
  3705. break;
  3706. case '.':
  3707. if (option.regexp) {
  3708. warningAt("Insecure '{a}'.", line,
  3709. from + l, c);
  3710. }
  3711. break;
  3712. case ']':
  3713. case '?':
  3714. case '{':
  3715. case '}':
  3716. case '+':
  3717. case '*':
  3718. warningAt("Unescaped '{a}'.", line,
  3719. from + l, c);
  3720. }
  3721. if (b) {
  3722. switch (s.charAt(l)) {
  3723. case '?':
  3724. case '+':
  3725. case '*':
  3726. l += 1;
  3727. if (s.charAt(l) === '?') {
  3728. l += 1;
  3729. }
  3730. break;
  3731. case '{':
  3732. l += 1;
  3733. c = s.charAt(l);
  3734. if (c < '0' || c > '9') {
  3735. warningAt(
  3736. "Expected a number and instead saw '{a}'.", line, from + l, c);
  3737. }
  3738. l += 1;
  3739. low = +c;
  3740. for (;;) {
  3741. c = s.charAt(l);
  3742. if (c < '0' || c > '9') {
  3743. break;
  3744. }
  3745. l += 1;
  3746. low = +c + (low * 10);
  3747. }
  3748. high = low;
  3749. if (c === ',') {
  3750. l += 1;
  3751. high = Infinity;
  3752. c = s.charAt(l);
  3753. if (c >= '0' && c <= '9') {
  3754. l += 1;
  3755. high = +c;
  3756. for (;;) {
  3757. c = s.charAt(l);
  3758. if (c < '0' || c > '9') {
  3759. break;
  3760. }
  3761. l += 1;
  3762. high = +c + (high * 10);
  3763. }
  3764. }
  3765. }
  3766. if (s.charAt(l) !== '}') {
  3767. warningAt(
  3768. "Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
  3769. } else {
  3770. l += 1;
  3771. }
  3772. if (s.charAt(l) === '?') {
  3773. l += 1;
  3774. }
  3775. if (low > high) {
  3776. warningAt(
  3777. "'{a}' should not be greater than '{b}'.", line, from + l, low, high);
  3778. }
  3779. }
  3780. }
  3781. }
  3782. c = s.substr(0, l - 1);
  3783. character += l;
  3784. s = s.substr(l);
  3785. return it('(regexp)', c);
  3786. }
  3787. return it('(punctuator)', t);
  3788. // punctuator
  3789. case '#':
  3790. return it('(punctuator)', t);
  3791. default:
  3792. return it('(punctuator)', t);
  3793. }
  3794. }
  3795. }
  3796. }
  3797. };
  3798. }());
  3799. function addlabel(t, type) {
  3800. if (t === 'hasOwnProperty') {
  3801. warning("'hasOwnProperty' is a really bad name.");
  3802. }
  3803. // Define t in the current function in the current scope.
  3804. if (is_own(funct, t) && !funct['(global)']) {
  3805. if (funct[t] === true) {
  3806. if (option.latedef)
  3807. warning("'{a}' was used before it was defined.", nexttoken, t);
  3808. } else {
  3809. if (!option.shadow && type !== "exception")
  3810. warning("'{a}' is already defined.", nexttoken, t);
  3811. }
  3812. }
  3813. funct[t] = type;
  3814. if (funct['(global)']) {
  3815. global[t] = funct;
  3816. if (is_own(implied, t)) {
  3817. if (option.latedef)
  3818. warning("'{a}' was used before it was defined.", nexttoken, t);
  3819. delete implied[t];
  3820. }
  3821. } else {
  3822. scope[t] = funct;
  3823. }
  3824. }
  3825. function doOption() {
  3826. var b, obj, filter, o = nexttoken.value, t, v;
  3827. switch (o) {
  3828. case '*/':
  3829. error("Unbegun comment.");
  3830. break;
  3831. case '/*members':
  3832. case '/*member':
  3833. o = '/*members';
  3834. if (!membersOnly) {
  3835. membersOnly = {};
  3836. }
  3837. obj = membersOnly;
  3838. break;
  3839. case '/*jshint':
  3840. case '/*jslint':
  3841. obj = option;
  3842. filter = boolOptions;
  3843. break;
  3844. case '/*global':
  3845. obj = predefined;
  3846. break;
  3847. default:
  3848. error("What?");
  3849. }
  3850. t = lex.token();
  3851. loop: for (;;) {
  3852. for (;;) {
  3853. if (t.type === 'special' && t.value === '*/') {
  3854. break loop;
  3855. }
  3856. if (t.id !== '(endline)' && t.id !== ',') {
  3857. break;
  3858. }
  3859. t = lex.token();
  3860. }
  3861. if (t.type !== '(string)' && t.type !== '(identifier)' &&
  3862. o !== '/*members') {
  3863. error("Bad option.", t);
  3864. }
  3865. v = lex.token();
  3866. if (v.id === ':') {
  3867. v = lex.token();
  3868. if (obj === membersOnly) {
  3869. error("Expected '{a}' and instead saw '{b}'.",
  3870. t, '*/', ':');
  3871. }
  3872. if (o === '/*jshint') {
  3873. checkOption(t.value, t);
  3874. }
  3875. if (t.value === 'indent' && (o === '/*jshint' || o === '/*jslint')) {
  3876. b = +v.value;
  3877. if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
  3878. Math.floor(b) !== b) {
  3879. error("Expected a small integer and instead saw '{a}'.",
  3880. v, v.value);
  3881. }
  3882. obj.white = true;
  3883. obj.indent = b;
  3884. } else if (t.value === 'maxerr' && (o === '/*jshint' || o === '/*jslint')) {
  3885. b = +v.value;
  3886. if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
  3887. Math.floor(b) !== b) {
  3888. error("Expected a small integer and instead saw '{a}'.",
  3889. v, v.value);
  3890. }
  3891. obj.maxerr = b;
  3892. } else if (t.value === 'maxlen' && (o === '/*jshint' || o === '/*jslint')) {
  3893. b = +v.value;
  3894. if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
  3895. Math.floor(b) !== b) {
  3896. error("Expected a small integer and instead saw '{a}'.",
  3897. v, v.value);
  3898. }
  3899. obj.maxlen = b;
  3900. } else if (t.value === 'validthis') {
  3901. if (funct['(global)']) {
  3902. error("Option 'validthis' can't be used in a global scope.");
  3903. } else {
  3904. if (v.value === 'true' || v.value === 'false')
  3905. obj[t.value] = v.value === 'true';
  3906. else
  3907. error("Bad option value.", v);
  3908. }
  3909. } else if (v.value === 'true') {
  3910. obj[t.value] = true;
  3911. } else if (v.value === 'false') {
  3912. obj[t.value] = false;
  3913. } else {
  3914. error("Bad option value.", v);
  3915. }
  3916. t = lex.token();
  3917. } else {
  3918. if (o === '/*jshint' || o === '/*jslint') {
  3919. error("Missing option value.", t);
  3920. }
  3921. obj[t.value] = false;
  3922. t = v;
  3923. }
  3924. }
  3925. if (filter) {
  3926. assume();
  3927. }
  3928. }
  3929. // We need a peek function. If it has an argument, it peeks that much farther
  3930. // ahead. It is used to distinguish
  3931. // for ( var i in ...
  3932. // from
  3933. // for ( var i = ...
  3934. function peek(p) {
  3935. var i = p || 0, j = 0, t;
  3936. while (j <= i) {
  3937. t = lookahead[j];
  3938. if (!t) {
  3939. t = lookahead[j] = lex.token();
  3940. }
  3941. j += 1;
  3942. }
  3943. return t;
  3944. }
  3945. // Produce the next token. It looks for programming errors.
  3946. function advance(id, t) {
  3947. switch (token.id) {
  3948. case '(number)':
  3949. if (nexttoken.id === '.') {
  3950. warning("A dot following a number can be confused with a decimal point.", token);
  3951. }
  3952. break;
  3953. case '-':
  3954. if (nexttoken.id === '-' || nexttoken.id === '--') {
  3955. warning("Confusing minusses.");
  3956. }
  3957. break;
  3958. case '+':
  3959. if (nexttoken.id === '+' || nexttoken.id === '++') {
  3960. warning("Confusing plusses.");
  3961. }
  3962. break;
  3963. }
  3964. if (token.type === '(string)' || token.identifier) {
  3965. anonname = token.value;
  3966. }
  3967. if (id && nexttoken.id !== id) {
  3968. if (t) {
  3969. if (nexttoken.id === '(end)') {
  3970. warning("Unmatched '{a}'.", t, t.id);
  3971. } else {
  3972. warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
  3973. nexttoken, id, t.id, t.line, nexttoken.value);
  3974. }
  3975. } else if (nexttoken.type !== '(identifier)' ||
  3976. nexttoken.value !== id) {
  3977. warning("Expected '{a}' and instead saw '{b}'.",
  3978. nexttoken, id, nexttoken.value);
  3979. }
  3980. }
  3981. prevtoken = token;
  3982. token = nexttoken;
  3983. for (;;) {
  3984. nexttoken = lookahead.shift() || lex.token();
  3985. if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
  3986. return;
  3987. }
  3988. if (nexttoken.type === 'special') {
  3989. doOption();
  3990. } else {
  3991. if (nexttoken.id !== '(endline)') {
  3992. break;
  3993. }
  3994. }
  3995. }
  3996. }
  3997. // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it
  3998. // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is
  3999. // like .nud except that it is only used on the first token of a statement.
  4000. // Having .fud makes it much easier to define statement-oriented languages like
  4001. // JavaScript. I retained Pratt's nomenclature.
  4002. // .nud Null denotation
  4003. // .fud First null denotation
  4004. // .led Left denotation
  4005. // lbp Left binding power
  4006. // rbp Right binding power
  4007. // They are elements of the parsing method called Top Down Operator Precedence.
  4008. function expression(rbp, initial) {
  4009. var left, isArray = false, isObject = false;
  4010. if (nexttoken.id === '(end)')
  4011. error("Unexpected early end of program.", token);
  4012. advance();
  4013. if (initial) {
  4014. anonname = 'anonymous';
  4015. funct['(verb)'] = token.value;
  4016. }
  4017. if (initial === true && token.fud) {
  4018. left = token.fud();
  4019. } else {
  4020. if (token.nud) {
  4021. left = token.nud();
  4022. } else {
  4023. if (nexttoken.type === '(number)' && token.id === '.') {
  4024. warning("A leading decimal point can be confused with a dot: '.{a}'.",
  4025. token, nexttoken.value);
  4026. advance();
  4027. return token;
  4028. } else {
  4029. error("Expected an identifier and instead saw '{a}'.",
  4030. token, token.id);
  4031. }
  4032. }
  4033. while (rbp < nexttoken.lbp) {
  4034. isArray = token.value === 'Array';
  4035. isObject = token.value === 'Object';
  4036. advance();
  4037. if (isArray && token.id === '(' && nexttoken.id === ')')
  4038. warning("Use the array literal notation [].", token);
  4039. if (isObject && token.id === '(' && nexttoken.id === ')')
  4040. warning("Use the object literal notation {}.", token);
  4041. if (token.led) {
  4042. left = token.led(left);
  4043. } else {
  4044. error("Expected an operator and instead saw '{a}'.",
  4045. token, token.id);
  4046. }
  4047. }
  4048. }
  4049. return left;
  4050. }
  4051. // Functions for conformance of style.
  4052. function adjacent(left, right) {
  4053. left = left || token;
  4054. right = right || nexttoken;
  4055. if (option.white) {
  4056. if (left.character !== right.from && left.line === right.line) {
  4057. left.from += (left.character - left.from);
  4058. warning("Unexpected space after '{a}'.", left, left.value);
  4059. }
  4060. }
  4061. }
  4062. function nobreak(left, right) {
  4063. left = left || token;
  4064. right = right || nexttoken;
  4065. if (option.white && (left.character !== right.from || left.line !== right.line)) {
  4066. warning("Unexpected space before '{a}'.", right, right.value);
  4067. }
  4068. }
  4069. function nospace(left, right) {
  4070. left = left || token;
  4071. right = right || nexttoken;
  4072. if (option.white && !left.comment) {
  4073. if (left.line === right.line) {
  4074. adjacent(left, right);
  4075. }
  4076. }
  4077. }
  4078. function nonadjacent(left, right) {
  4079. if (option.white) {
  4080. left = left || token;
  4081. right = right || nexttoken;
  4082. if (left.line === right.line && left.character === right.from) {
  4083. left.from += (left.character - left.from);
  4084. warning("Missing space after '{a}'.",
  4085. left, left.value);
  4086. }
  4087. }
  4088. }
  4089. function nobreaknonadjacent(left, right) {
  4090. left = left || token;
  4091. right = right || nexttoken;
  4092. if (!option.laxbreak && left.line !== right.line) {
  4093. warning("Bad line breaking before '{a}'.", right, right.id);
  4094. } else if (option.white) {
  4095. left = left || token;
  4096. right = right || nexttoken;
  4097. if (left.character === right.from) {
  4098. left.from += (left.character - left.from);
  4099. warning("Missing space after '{a}'.",
  4100. left, left.value);
  4101. }
  4102. }
  4103. }
  4104. function indentation(bias) {
  4105. var i;
  4106. if (option.white && nexttoken.id !== '(end)') {
  4107. i = indent + (bias || 0);
  4108. if (nexttoken.from !== i) {
  4109. warning(
  4110. "Expected '{a}' to have an indentation at {b} instead at {c}.",
  4111. nexttoken, nexttoken.value, i, nexttoken.from);
  4112. }
  4113. }
  4114. }
  4115. function nolinebreak(t) {
  4116. t = t || token;
  4117. if (t.line !== nexttoken.line) {
  4118. warning("Line breaking error '{a}'.", t, t.value);
  4119. }
  4120. }
  4121. function comma() {
  4122. if (token.line !== nexttoken.line) {
  4123. if (!option.laxcomma) {
  4124. if (comma.first) {
  4125. warning("Comma warnings can be turned off with 'laxcomma'");
  4126. comma.first = false;
  4127. }
  4128. warning("Bad line breaking before '{a}'.", token, nexttoken.id);
  4129. }
  4130. } else if (!token.comment && token.character !== nexttoken.from && option.white) {
  4131. token.from += (token.character - token.from);
  4132. warning("Unexpected space after '{a}'.", token, token.value);
  4133. }
  4134. advance(',');
  4135. nonadjacent(token, nexttoken);
  4136. }
  4137. // Functional constructors for making the symbols that will be inherited by
  4138. // tokens.
  4139. function symbol(s, p) {
  4140. var x = syntax[s];
  4141. if (!x || typeof x !== 'object') {
  4142. syntax[s] = x = {
  4143. id: s,
  4144. lbp: p,
  4145. value: s
  4146. };
  4147. }
  4148. return x;
  4149. }
  4150. function delim(s) {
  4151. return symbol(s, 0);
  4152. }
  4153. function stmt(s, f) {
  4154. var x = delim(s);
  4155. x.identifier = x.reserved = true;
  4156. x.fud = f;
  4157. return x;
  4158. }
  4159. function blockstmt(s, f) {
  4160. var x = stmt(s, f);
  4161. x.block = true;
  4162. return x;
  4163. }
  4164. function reserveName(x) {
  4165. var c = x.id.charAt(0);
  4166. if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
  4167. x.identifier = x.reserved = true;
  4168. }
  4169. return x;
  4170. }
  4171. function prefix(s, f) {
  4172. var x = symbol(s, 150);
  4173. reserveName(x);
  4174. x.nud = (typeof f === 'function') ? f : function () {
  4175. this.right = expression(150);
  4176. this.arity = 'unary';
  4177. if (this.id === '++' || this.id === '--') {
  4178. if (option.plusplus) {
  4179. warning("Unexpected use of '{a}'.", this, this.id);
  4180. } else if ((!this.right.identifier || this.right.reserved) &&
  4181. this.right.id !== '.' && this.right.id !== '[') {
  4182. warning("Bad operand.", this);
  4183. }
  4184. }
  4185. return this;
  4186. };
  4187. return x;
  4188. }
  4189. function type(s, f) {
  4190. var x = delim(s);
  4191. x.type = s;
  4192. x.nud = f;
  4193. return x;
  4194. }
  4195. function reserve(s, f) {
  4196. var x = type(s, f);
  4197. x.identifier = x.reserved = true;
  4198. return x;
  4199. }
  4200. function reservevar(s, v) {
  4201. return reserve(s, function () {
  4202. if (typeof v === 'function') {
  4203. v(this);
  4204. }
  4205. return this;
  4206. });
  4207. }
  4208. function infix(s, f, p, w) {
  4209. var x = symbol(s, p);
  4210. reserveName(x);
  4211. x.led = function (left) {
  4212. if (!w) {
  4213. nobreaknonadjacent(prevtoken, token);
  4214. nonadjacent(token, nexttoken);
  4215. }
  4216. if (s === "in" && left.id === "!") {
  4217. warning("Confusing use of '{a}'.", left, '!');
  4218. }
  4219. if (typeof f === 'function') {
  4220. return f(left, this);
  4221. } else {
  4222. this.left = left;
  4223. this.right = expression(p);
  4224. return this;
  4225. }
  4226. };
  4227. return x;
  4228. }
  4229. function relation(s, f) {
  4230. var x = symbol(s, 100);
  4231. x.led = function (left) {
  4232. nobreaknonadjacent(prevtoken, token);
  4233. nonadjacent(token, nexttoken);
  4234. var right = expression(100);
  4235. if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) {
  4236. warning("Use the isNaN function to compare with NaN.", this);
  4237. } else if (f) {
  4238. f.apply(this, [left, right]);
  4239. }
  4240. if (left.id === '!') {
  4241. warning("Confusing use of '{a}'.", left, '!');
  4242. }
  4243. if (right.id === '!') {
  4244. warning("Confusing use of '{a}'.", right, '!');
  4245. }
  4246. this.left = left;
  4247. this.right = right;
  4248. return this;
  4249. };
  4250. return x;
  4251. }
  4252. function isPoorRelation(node) {
  4253. return node &&
  4254. ((node.type === '(number)' && +node.value === 0) ||
  4255. (node.type === '(string)' && node.value === '') ||
  4256. (node.type === 'null' && !option.eqnull) ||
  4257. node.type === 'true' ||
  4258. node.type === 'false' ||
  4259. node.type === 'undefined');
  4260. }
  4261. function assignop(s, f) {
  4262. symbol(s, 20).exps = true;
  4263. return infix(s, function (left, that) {
  4264. var l;
  4265. that.left = left;
  4266. if (predefined[left.value] === false &&
  4267. scope[left.value]['(global)'] === true) {
  4268. warning("Read only.", left);
  4269. } else if (left['function']) {
  4270. warning("'{a}' is a function.", left, left.value);
  4271. }
  4272. if (left) {
  4273. if (option.esnext && funct[left.value] === 'const') {
  4274. warning("Attempting to override '{a}' which is a constant", left, left.value);
  4275. }
  4276. if (left.id === '.' || left.id === '[') {
  4277. if (!left.left || left.left.value === 'arguments') {
  4278. warning('Bad assignment.', that);
  4279. }
  4280. that.right = expression(19);
  4281. return that;
  4282. } else if (left.identifier && !left.reserved) {
  4283. if (funct[left.value] === 'exception') {
  4284. warning("Do not assign to the exception parameter.", left);
  4285. }
  4286. that.right = expression(19);
  4287. return that;
  4288. }
  4289. if (left === syntax['function']) {
  4290. warning(
  4291. "Expected an identifier in an assignment and instead saw a function invocation.",
  4292. token);
  4293. }
  4294. }
  4295. error("Bad assignment.", that);
  4296. }, 20);
  4297. }
  4298. function bitwise(s, f, p) {
  4299. var x = symbol(s, p);
  4300. reserveName(x);
  4301. x.led = (typeof f === 'function') ? f : function (left) {
  4302. if (option.bitwise) {
  4303. warning("Unexpected use of '{a}'.", this, this.id);
  4304. }
  4305. this.left = left;
  4306. this.right = expression(p);
  4307. return this;
  4308. };
  4309. return x;
  4310. }
  4311. function bitwiseassignop(s) {
  4312. symbol(s, 20).exps = true;
  4313. return infix(s, function (left, that) {
  4314. if (option.bitwise) {
  4315. warning("Unexpected use of '{a}'.", that, that.id);
  4316. }
  4317. nonadjacent(prevtoken, token);
  4318. nonadjacent(token, nexttoken);
  4319. if (left) {
  4320. if (left.id === '.' || left.id === '[' ||
  4321. (left.identifier && !left.reserved)) {
  4322. expression(19);
  4323. return that;
  4324. }
  4325. if (left === syntax['function']) {
  4326. warning(
  4327. "Expected an identifier in an assignment, and instead saw a function invocation.",
  4328. token);
  4329. }
  4330. return that;
  4331. }
  4332. error("Bad assignment.", that);
  4333. }, 20);
  4334. }
  4335. function suffix(s, f) {
  4336. var x = symbol(s, 150);
  4337. x.led = function (left) {
  4338. if (option.plusplus) {
  4339. warning("Unexpected use of '{a}'.", this, this.id);
  4340. } else if ((!left.identifier || left.reserved) &&
  4341. left.id !== '.' && left.id !== '[') {
  4342. warning("Bad operand.", this);
  4343. }
  4344. this.left = left;
  4345. return this;
  4346. };
  4347. return x;
  4348. }
  4349. // fnparam means that this identifier is being defined as a function
  4350. // argument (see identifier())
  4351. function optionalidentifier(fnparam) {
  4352. if (nexttoken.identifier) {
  4353. advance();
  4354. if (token.reserved && !option.es5) {
  4355. // `undefined` as a function param is a common pattern to protect
  4356. // against the case when somebody does `undefined = true` and
  4357. // help with minification. More info: https://gist.github.com/315916
  4358. if (!fnparam || token.value !== 'undefined') {
  4359. warning("Expected an identifier and instead saw '{a}' (a reserved word).",
  4360. token, token.id);
  4361. }
  4362. }
  4363. return token.value;
  4364. }
  4365. }
  4366. // fnparam means that this identifier is being defined as a function
  4367. // argument
  4368. function identifier(fnparam) {
  4369. var i = optionalidentifier(fnparam);
  4370. if (i) {
  4371. return i;
  4372. }
  4373. if (token.id === 'function' && nexttoken.id === '(') {
  4374. warning("Missing name in function declaration.");
  4375. } else {
  4376. error("Expected an identifier and instead saw '{a}'.",
  4377. nexttoken, nexttoken.value);
  4378. }
  4379. }
  4380. function reachable(s) {
  4381. var i = 0, t;
  4382. if (nexttoken.id !== ';' || noreach) {
  4383. return;
  4384. }
  4385. for (;;) {
  4386. t = peek(i);
  4387. if (t.reach) {
  4388. return;
  4389. }
  4390. if (t.id !== '(endline)') {
  4391. if (t.id === 'function') {
  4392. if (!option.latedef) {
  4393. break;
  4394. }
  4395. warning(
  4396. "Inner functions should be listed at the top of the outer function.", t);
  4397. break;
  4398. }
  4399. warning("Unreachable '{a}' after '{b}'.", t, t.value, s);
  4400. break;
  4401. }
  4402. i += 1;
  4403. }
  4404. }
  4405. function statement(noindent) {
  4406. var i = indent, r, s = scope, t = nexttoken;
  4407. if (t.id === ";") {
  4408. advance(";");
  4409. return;
  4410. }
  4411. // Is this a labelled statement?
  4412. if (t.identifier && !t.reserved && peek().id === ':') {
  4413. advance();
  4414. advance(':');
  4415. scope = Object.create(s);
  4416. addlabel(t.value, 'label');
  4417. if (!nexttoken.labelled) {
  4418. warning("Label '{a}' on {b} statement.",
  4419. nexttoken, t.value, nexttoken.value);
  4420. }
  4421. if (jx.test(t.value + ':')) {
  4422. warning("Label '{a}' looks like a javascript url.",
  4423. t, t.value);
  4424. }
  4425. nexttoken.label = t.value;
  4426. t = nexttoken;
  4427. }
  4428. // Parse the statement.
  4429. if (!noindent) {
  4430. indentation();
  4431. }
  4432. r = expression(0, true);
  4433. // Look for the final semicolon.
  4434. if (!t.block) {
  4435. if (!option.expr && (!r || !r.exps)) {
  4436. warning("Expected an assignment or function call and instead saw an expression.",
  4437. token);
  4438. } else if (option.nonew && r.id === '(' && r.left.id === 'new') {
  4439. warning("Do not use 'new' for side effects.");
  4440. }
  4441. if (nexttoken.id === ',') {
  4442. return comma();
  4443. }
  4444. if (nexttoken.id !== ';') {
  4445. if (!option.asi) {
  4446. // If this is the last statement in a block that ends on
  4447. // the same line *and* option lastsemic is on, ignore the warning.
  4448. // Otherwise, complain about missing semicolon.
  4449. if (!option.lastsemic || nexttoken.id !== '}' ||
  4450. nexttoken.line !== token.line) {
  4451. warningAt("Missing semicolon.", token.line, token.character);
  4452. }
  4453. }
  4454. } else {
  4455. adjacent(token, nexttoken);
  4456. advance(';');
  4457. nonadjacent(token, nexttoken);
  4458. }
  4459. }
  4460. // Restore the indentation.
  4461. indent = i;
  4462. scope = s;
  4463. return r;
  4464. }
  4465. function statements(startLine) {
  4466. var a = [], f, p;
  4467. while (!nexttoken.reach && nexttoken.id !== '(end)') {
  4468. if (nexttoken.id === ';') {
  4469. p = peek();
  4470. if (!p || p.id !== "(") {
  4471. warning("Unnecessary semicolon.");
  4472. }
  4473. advance(';');
  4474. } else {
  4475. a.push(statement(startLine === nexttoken.line));
  4476. }
  4477. }
  4478. return a;
  4479. }
  4480. /*
  4481. * read all directives
  4482. * recognizes a simple form of asi, but always
  4483. * warns, if it is used
  4484. */
  4485. function directives() {
  4486. var i, p, pn;
  4487. for (;;) {
  4488. if (nexttoken.id === "(string)") {
  4489. p = peek(0);
  4490. if (p.id === "(endline)") {
  4491. i = 1;
  4492. do {
  4493. pn = peek(i);
  4494. i = i + 1;
  4495. } while (pn.id === "(endline)");
  4496. if (pn.id !== ";") {
  4497. if (pn.id !== "(string)" && pn.id !== "(number)" &&
  4498. pn.id !== "(regexp)" && pn.identifier !== true &&
  4499. pn.id !== "}") {
  4500. break;
  4501. }
  4502. warning("Missing semicolon.", nexttoken);
  4503. } else {
  4504. p = pn;
  4505. }
  4506. } else if (p.id === "}") {
  4507. // directive with no other statements, warn about missing semicolon
  4508. warning("Missing semicolon.", p);
  4509. } else if (p.id !== ";") {
  4510. break;
  4511. }
  4512. indentation();
  4513. advance();
  4514. if (directive[token.value]) {
  4515. warning("Unnecessary directive \"{a}\".", token, token.value);
  4516. }
  4517. if (token.value === "use strict") {
  4518. option.newcap = true;
  4519. option.undef = true;
  4520. }
  4521. // there's no directive negation, so always set to true
  4522. directive[token.value] = true;
  4523. if (p.id === ";") {
  4524. advance(";");
  4525. }
  4526. continue;
  4527. }
  4528. break;
  4529. }
  4530. }
  4531. /*
  4532. * Parses a single block. A block is a sequence of statements wrapped in
  4533. * braces.
  4534. *
  4535. * ordinary - true for everything but function bodies and try blocks.
  4536. * stmt - true if block can be a single statement (e.g. in if/for/while).
  4537. * isfunc - true if block is a function body
  4538. */
  4539. function block(ordinary, stmt, isfunc) {
  4540. var a,
  4541. b = inblock,
  4542. old_indent = indent,
  4543. m,
  4544. s = scope,
  4545. t,
  4546. line,
  4547. d;
  4548. inblock = ordinary;
  4549. if (!ordinary || !option.funcscope) scope = Object.create(scope);
  4550. nonadjacent(token, nexttoken);
  4551. t = nexttoken;
  4552. if (nexttoken.id === '{') {
  4553. advance('{');
  4554. line = token.line;
  4555. if (nexttoken.id !== '}') {
  4556. indent += option.indent;
  4557. while (!ordinary && nexttoken.from > indent) {
  4558. indent += option.indent;
  4559. }
  4560. if (isfunc) {
  4561. m = {};
  4562. for (d in directive) {
  4563. if (is_own(directive, d)) {
  4564. m[d] = directive[d];
  4565. }
  4566. }
  4567. directives();
  4568. if (option.strict && funct['(context)']['(global)']) {
  4569. if (!m["use strict"] && !directive["use strict"]) {
  4570. warning("Missing \"use strict\" statement.");
  4571. }
  4572. }
  4573. }
  4574. a = statements(line);
  4575. if (isfunc) {
  4576. directive = m;
  4577. }
  4578. indent -= option.indent;
  4579. if (line !== nexttoken.line) {
  4580. indentation();
  4581. }
  4582. } else if (line !== nexttoken.line) {
  4583. indentation();
  4584. }
  4585. advance('}', t);
  4586. indent = old_indent;
  4587. } else if (!ordinary) {
  4588. error("Expected '{a}' and instead saw '{b}'.",
  4589. nexttoken, '{', nexttoken.value);
  4590. } else {
  4591. if (!stmt || option.curly)
  4592. warning("Expected '{a}' and instead saw '{b}'.",
  4593. nexttoken, '{', nexttoken.value);
  4594. noreach = true;
  4595. indent += option.indent;
  4596. // test indentation only if statement is in new line
  4597. a = [statement(nexttoken.line === token.line)];
  4598. indent -= option.indent;
  4599. noreach = false;
  4600. }
  4601. funct['(verb)'] = null;
  4602. if (!ordinary || !option.funcscope) scope = s;
  4603. inblock = b;
  4604. if (ordinary && option.noempty && (!a || a.length === 0)) {
  4605. warning("Empty block.");
  4606. }
  4607. return a;
  4608. }
  4609. function countMember(m) {
  4610. if (membersOnly && typeof membersOnly[m] !== 'boolean') {
  4611. warning("Unexpected /*member '{a}'.", token, m);
  4612. }
  4613. if (typeof member[m] === 'number') {
  4614. member[m] += 1;
  4615. } else {
  4616. member[m] = 1;
  4617. }
  4618. }
  4619. function note_implied(token) {
  4620. var name = token.value, line = token.line, a = implied[name];
  4621. if (typeof a === 'function') {
  4622. a = false;
  4623. }
  4624. if (!a) {
  4625. a = [line];
  4626. implied[name] = a;
  4627. } else if (a[a.length - 1] !== line) {
  4628. a.push(line);
  4629. }
  4630. }
  4631. // Build the syntax table by declaring the syntactic elements of the language.
  4632. type('(number)', function () {
  4633. return this;
  4634. });
  4635. type('(string)', function () {
  4636. return this;
  4637. });
  4638. syntax['(identifier)'] = {
  4639. type: '(identifier)',
  4640. lbp: 0,
  4641. identifier: true,
  4642. nud: function () {
  4643. var v = this.value,
  4644. s = scope[v],
  4645. f;
  4646. if (typeof s === 'function') {
  4647. // Protection against accidental inheritance.
  4648. s = undefined;
  4649. } else if (typeof s === 'boolean') {
  4650. f = funct;
  4651. funct = functions[0];
  4652. addlabel(v, 'var');
  4653. s = funct;
  4654. funct = f;
  4655. }
  4656. // The name is in scope and defined in the current function.
  4657. if (funct === s) {
  4658. // Change 'unused' to 'var', and reject labels.
  4659. switch (funct[v]) {
  4660. case 'unused':
  4661. funct[v] = 'var';
  4662. break;
  4663. case 'unction':
  4664. funct[v] = 'function';
  4665. this['function'] = true;
  4666. break;
  4667. case 'function':
  4668. this['function'] = true;
  4669. break;
  4670. case 'label':
  4671. warning("'{a}' is a statement label.", token, v);
  4672. break;
  4673. }
  4674. } else if (funct['(global)']) {
  4675. // The name is not defined in the function. If we are in the global
  4676. // scope, then we have an undefined variable.
  4677. //
  4678. // Operators typeof and delete do not raise runtime errors even if
  4679. // the base object of a reference is null so no need to display warning
  4680. // if we're inside of typeof or delete.
  4681. if (option.undef && typeof predefined[v] !== 'boolean') {
  4682. // Attempting to subscript a null reference will throw an
  4683. // error, even within the typeof and delete operators
  4684. if (!(anonname === 'typeof' || anonname === 'delete') ||
  4685. (nexttoken && (nexttoken.value === '.' || nexttoken.value === '['))) {
  4686. isundef(funct, "'{a}' is not defined.", token, v);
  4687. }
  4688. }
  4689. note_implied(token);
  4690. } else {
  4691. // If the name is already defined in the current
  4692. // function, but not as outer, then there is a scope error.
  4693. switch (funct[v]) {
  4694. case 'closure':
  4695. case 'function':
  4696. case 'var':
  4697. case 'unused':
  4698. warning("'{a}' used out of scope.", token, v);
  4699. break;
  4700. case 'label':
  4701. warning("'{a}' is a statement label.", token, v);
  4702. break;
  4703. case 'outer':
  4704. case 'global':
  4705. break;
  4706. default:
  4707. // If the name is defined in an outer function, make an outer entry,
  4708. // and if it was unused, make it var.
  4709. if (s === true) {
  4710. funct[v] = true;
  4711. } else if (s === null) {
  4712. warning("'{a}' is not allowed.", token, v);
  4713. note_implied(token);
  4714. } else if (typeof s !== 'object') {
  4715. // Operators typeof and delete do not raise runtime errors even
  4716. // if the base object of a reference is null so no need to
  4717. // display warning if we're inside of typeof or delete.
  4718. if (option.undef) {
  4719. // Attempting to subscript a null reference will throw an
  4720. // error, even within the typeof and delete operators
  4721. if (!(anonname === 'typeof' || anonname === 'delete') ||
  4722. (nexttoken &&
  4723. (nexttoken.value === '.' || nexttoken.value === '['))) {
  4724. isundef(funct, "'{a}' is not defined.", token, v);
  4725. }
  4726. }
  4727. funct[v] = true;
  4728. note_implied(token);
  4729. } else {
  4730. switch (s[v]) {
  4731. case 'function':
  4732. case 'unction':
  4733. this['function'] = true;
  4734. s[v] = 'closure';
  4735. funct[v] = s['(global)'] ? 'global' : 'outer';
  4736. break;
  4737. case 'var':
  4738. case 'unused':
  4739. s[v] = 'closure';
  4740. funct[v] = s['(global)'] ? 'global' : 'outer';
  4741. break;
  4742. case 'closure':
  4743. case 'parameter':
  4744. funct[v] = s['(global)'] ? 'global' : 'outer';
  4745. break;
  4746. case 'label':
  4747. warning("'{a}' is a statement label.", token, v);
  4748. }
  4749. }
  4750. }
  4751. }
  4752. return this;
  4753. },
  4754. led: function () {
  4755. error("Expected an operator and instead saw '{a}'.",
  4756. nexttoken, nexttoken.value);
  4757. }
  4758. };
  4759. type('(regexp)', function () {
  4760. return this;
  4761. });
  4762. // ECMAScript parser
  4763. delim('(endline)');
  4764. delim('(begin)');
  4765. delim('(end)').reach = true;
  4766. delim('</').reach = true;
  4767. delim('<!');
  4768. delim('<!--');
  4769. delim('-->');
  4770. delim('(error)').reach = true;
  4771. delim('}').reach = true;
  4772. delim(')');
  4773. delim(']');
  4774. delim('"').reach = true;
  4775. delim("'").reach = true;
  4776. delim(';');
  4777. delim(':').reach = true;
  4778. delim(',');
  4779. delim('#');
  4780. delim('@');
  4781. reserve('else');
  4782. reserve('case').reach = true;
  4783. reserve('catch');
  4784. reserve('default').reach = true;
  4785. reserve('finally');
  4786. reservevar('arguments', function (x) {
  4787. if (directive['use strict'] && funct['(global)']) {
  4788. warning("Strict violation.", x);
  4789. }
  4790. });
  4791. reservevar('eval');
  4792. reservevar('false');
  4793. reservevar('Infinity');
  4794. reservevar('NaN');
  4795. reservevar('null');
  4796. reservevar('this', function (x) {
  4797. if (directive['use strict'] && !option.validthis && ((funct['(statement)'] &&
  4798. funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) {
  4799. warning("Possible strict violation.", x);
  4800. }
  4801. });
  4802. reservevar('true');
  4803. reservevar('undefined');
  4804. assignop('=', 'assign', 20);
  4805. assignop('+=', 'assignadd', 20);
  4806. assignop('-=', 'assignsub', 20);
  4807. assignop('*=', 'assignmult', 20);
  4808. assignop('/=', 'assigndiv', 20).nud = function () {
  4809. error("A regular expression literal can be confused with '/='.");
  4810. };
  4811. assignop('%=', 'assignmod', 20);
  4812. bitwiseassignop('&=', 'assignbitand', 20);
  4813. bitwiseassignop('|=', 'assignbitor', 20);
  4814. bitwiseassignop('^=', 'assignbitxor', 20);
  4815. bitwiseassignop('<<=', 'assignshiftleft', 20);
  4816. bitwiseassignop('>>=', 'assignshiftright', 20);
  4817. bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20);
  4818. infix('?', function (left, that) {
  4819. that.left = left;
  4820. that.right = expression(10);
  4821. advance(':');
  4822. that['else'] = expression(10);
  4823. return that;
  4824. }, 30);
  4825. infix('||', 'or', 40);
  4826. infix('&&', 'and', 50);
  4827. bitwise('|', 'bitor', 70);
  4828. bitwise('^', 'bitxor', 80);
  4829. bitwise('&', 'bitand', 90);
  4830. relation('==', function (left, right) {
  4831. var eqnull = option.eqnull && (left.value === 'null' || right.value === 'null');
  4832. if (!eqnull && option.eqeqeq)
  4833. warning("Expected '{a}' and instead saw '{b}'.", this, '===', '==');
  4834. else if (isPoorRelation(left))
  4835. warning("Use '{a}' to compare with '{b}'.", this, '===', left.value);
  4836. else if (isPoorRelation(right))
  4837. warning("Use '{a}' to compare with '{b}'.", this, '===', right.value);
  4838. return this;
  4839. });
  4840. relation('===');
  4841. relation('!=', function (left, right) {
  4842. var eqnull = option.eqnull &&
  4843. (left.value === 'null' || right.value === 'null');
  4844. if (!eqnull && option.eqeqeq) {
  4845. warning("Expected '{a}' and instead saw '{b}'.",
  4846. this, '!==', '!=');
  4847. } else if (isPoorRelation(left)) {
  4848. warning("Use '{a}' to compare with '{b}'.",
  4849. this, '!==', left.value);
  4850. } else if (isPoorRelation(right)) {
  4851. warning("Use '{a}' to compare with '{b}'.",
  4852. this, '!==', right.value);
  4853. }
  4854. return this;
  4855. });
  4856. relation('!==');
  4857. relation('<');
  4858. relation('>');
  4859. relation('<=');
  4860. relation('>=');
  4861. bitwise('<<', 'shiftleft', 120);
  4862. bitwise('>>', 'shiftright', 120);
  4863. bitwise('>>>', 'shiftrightunsigned', 120);
  4864. infix('in', 'in', 120);
  4865. infix('instanceof', 'instanceof', 120);
  4866. infix('+', function (left, that) {
  4867. var right = expression(130);
  4868. if (left && right && left.id === '(string)' && right.id === '(string)') {
  4869. left.value += right.value;
  4870. left.character = right.character;
  4871. if (!option.scripturl && jx.test(left.value)) {
  4872. warning("JavaScript URL.", left);
  4873. }
  4874. return left;
  4875. }
  4876. that.left = left;
  4877. that.right = right;
  4878. return that;
  4879. }, 130);
  4880. prefix('+', 'num');
  4881. prefix('+++', function () {
  4882. warning("Confusing pluses.");
  4883. this.right = expression(150);
  4884. this.arity = 'unary';
  4885. return this;
  4886. });
  4887. infix('+++', function (left) {
  4888. warning("Confusing pluses.");
  4889. this.left = left;
  4890. this.right = expression(130);
  4891. return this;
  4892. }, 130);
  4893. infix('-', 'sub', 130);
  4894. prefix('-', 'neg');
  4895. prefix('---', function () {
  4896. warning("Confusing minuses.");
  4897. this.right = expression(150);
  4898. this.arity = 'unary';
  4899. return this;
  4900. });
  4901. infix('---', function (left) {
  4902. warning("Confusing minuses.");
  4903. this.left = left;
  4904. this.right = expression(130);
  4905. return this;
  4906. }, 130);
  4907. infix('*', 'mult', 140);
  4908. infix('/', 'div', 140);
  4909. infix('%', 'mod', 140);
  4910. suffix('++', 'postinc');
  4911. prefix('++', 'preinc');
  4912. syntax['++'].exps = true;
  4913. suffix('--', 'postdec');
  4914. prefix('--', 'predec');
  4915. syntax['--'].exps = true;
  4916. prefix('delete', function () {
  4917. var p = expression(0);
  4918. if (!p || (p.id !== '.' && p.id !== '[')) {
  4919. warning("Variables should not be deleted.");
  4920. }
  4921. this.first = p;
  4922. return this;
  4923. }).exps = true;
  4924. prefix('~', function () {
  4925. if (option.bitwise) {
  4926. warning("Unexpected '{a}'.", this, '~');
  4927. }
  4928. expression(150);
  4929. return this;
  4930. });
  4931. prefix('!', function () {
  4932. this.right = expression(150);
  4933. this.arity = 'unary';
  4934. if (bang[this.right.id] === true) {
  4935. warning("Confusing use of '{a}'.", this, '!');
  4936. }
  4937. return this;
  4938. });
  4939. prefix('typeof', 'typeof');
  4940. prefix('new', function () {
  4941. var c = expression(155), i;
  4942. if (c && c.id !== 'function') {
  4943. if (c.identifier) {
  4944. c['new'] = true;
  4945. switch (c.value) {
  4946. case 'Number':
  4947. case 'String':
  4948. case 'Boolean':
  4949. case 'Math':
  4950. case 'JSON':
  4951. warning("Do not use {a} as a constructor.", token, c.value);
  4952. break;
  4953. case 'Function':
  4954. if (!option.evil) {
  4955. warning("The Function constructor is eval.");
  4956. }
  4957. break;
  4958. case 'Date':
  4959. case 'RegExp':
  4960. break;
  4961. default:
  4962. if (c.id !== 'function') {
  4963. i = c.value.substr(0, 1);
  4964. if (option.newcap && (i < 'A' || i > 'Z')) {
  4965. warning("A constructor name should start with an uppercase letter.",
  4966. token);
  4967. }
  4968. }
  4969. }
  4970. } else {
  4971. if (c.id !== '.' && c.id !== '[' && c.id !== '(') {
  4972. warning("Bad constructor.", token);
  4973. }
  4974. }
  4975. } else {
  4976. if (!option.supernew)
  4977. warning("Weird construction. Delete 'new'.", this);
  4978. }
  4979. adjacent(token, nexttoken);
  4980. if (nexttoken.id !== '(' && !option.supernew) {
  4981. warning("Missing '()' invoking a constructor.");
  4982. }
  4983. this.first = c;
  4984. return this;
  4985. });
  4986. syntax['new'].exps = true;
  4987. prefix('void').exps = true;
  4988. infix('.', function (left, that) {
  4989. adjacent(prevtoken, token);
  4990. nobreak();
  4991. var m = identifier();
  4992. if (typeof m === 'string') {
  4993. countMember(m);
  4994. }
  4995. that.left = left;
  4996. that.right = m;
  4997. if (left && left.value === 'arguments' && (m === 'callee' || m === 'caller')) {
  4998. if (option.noarg)
  4999. warning("Avoid arguments.{a}.", left, m);
  5000. else if (directive['use strict'])
  5001. error('Strict violation.');
  5002. } else if (!option.evil && left && left.value === 'document' &&
  5003. (m === 'write' || m === 'writeln')) {
  5004. warning("document.write can be a form of eval.", left);
  5005. }
  5006. if (!option.evil && (m === 'eval' || m === 'execScript')) {
  5007. warning('eval is evil.');
  5008. }
  5009. return that;
  5010. }, 160, true);
  5011. infix('(', function (left, that) {
  5012. if (prevtoken.id !== '}' && prevtoken.id !== ')') {
  5013. nobreak(prevtoken, token);
  5014. }
  5015. nospace();
  5016. if (option.immed && !left.immed && left.id === 'function') {
  5017. warning("Wrap an immediate function invocation in parentheses " +
  5018. "to assist the reader in understanding that the expression " +
  5019. "is the result of a function, and not the function itself.");
  5020. }
  5021. var n = 0,
  5022. p = [];
  5023. if (left) {
  5024. if (left.type === '(identifier)') {
  5025. if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
  5026. if (left.value !== 'Number' && left.value !== 'String' &&
  5027. left.value !== 'Boolean' &&
  5028. left.value !== 'Date') {
  5029. if (left.value === 'Math') {
  5030. warning("Math is not a function.", left);
  5031. } else if (option.newcap) {
  5032. warning(
  5033. "Missing 'new' prefix when invoking a constructor.", left);
  5034. }
  5035. }
  5036. }
  5037. }
  5038. }
  5039. if (nexttoken.id !== ')') {
  5040. for (;;) {
  5041. p[p.length] = expression(10);
  5042. n += 1;
  5043. if (nexttoken.id !== ',') {
  5044. break;
  5045. }
  5046. comma();
  5047. }
  5048. }
  5049. advance(')');
  5050. nospace(prevtoken, token);
  5051. if (typeof left === 'object') {
  5052. if (left.value === 'parseInt' && n === 1) {
  5053. warning("Missing radix parameter.", left);
  5054. }
  5055. if (!option.evil) {
  5056. if (left.value === 'eval' || left.value === 'Function' ||
  5057. left.value === 'execScript') {
  5058. warning("eval is evil.", left);
  5059. } else if (p[0] && p[0].id === '(string)' &&
  5060. (left.value === 'setTimeout' ||
  5061. left.value === 'setInterval')) {
  5062. warning(
  5063. "Implied eval is evil. Pass a function instead of a string.", left);
  5064. }
  5065. }
  5066. if (!left.identifier && left.id !== '.' && left.id !== '[' &&
  5067. left.id !== '(' && left.id !== '&&' && left.id !== '||' &&
  5068. left.id !== '?') {
  5069. warning("Bad invocation.", left);
  5070. }
  5071. }
  5072. that.left = left;
  5073. return that;
  5074. }, 155, true).exps = true;
  5075. prefix('(', function () {
  5076. nospace();
  5077. if (nexttoken.id === 'function') {
  5078. nexttoken.immed = true;
  5079. }
  5080. var v = expression(0);
  5081. advance(')', this);
  5082. nospace(prevtoken, token);
  5083. if (option.immed && v.id === 'function') {
  5084. if (nexttoken.id === '(' ||
  5085. (nexttoken.id === '.' && (peek().value === 'call' || peek().value === 'apply'))) {
  5086. warning(
  5087. "Move the invocation into the parens that contain the function.", nexttoken);
  5088. } else {
  5089. warning(
  5090. "Do not wrap function literals in parens unless they are to be immediately invoked.",
  5091. this);
  5092. }
  5093. }
  5094. return v;
  5095. });
  5096. infix('[', function (left, that) {
  5097. nobreak(prevtoken, token);
  5098. nospace();
  5099. var e = expression(0), s;
  5100. if (e && e.type === '(string)') {
  5101. if (!option.evil && (e.value === 'eval' || e.value === 'execScript')) {
  5102. warning("eval is evil.", that);
  5103. }
  5104. countMember(e.value);
  5105. if (!option.sub && ix.test(e.value)) {
  5106. s = syntax[e.value];
  5107. if (!s || !s.reserved) {
  5108. warning("['{a}'] is better written in dot notation.",
  5109. e, e.value);
  5110. }
  5111. }
  5112. }
  5113. advance(']', that);
  5114. nospace(prevtoken, token);
  5115. that.left = left;
  5116. that.right = e;
  5117. return that;
  5118. }, 160, true);
  5119. prefix('[', function () {
  5120. var b = token.line !== nexttoken.line;
  5121. this.first = [];
  5122. if (b) {
  5123. indent += option.indent;
  5124. if (nexttoken.from === indent + option.indent) {
  5125. indent += option.indent;
  5126. }
  5127. }
  5128. while (nexttoken.id !== '(end)') {
  5129. while (nexttoken.id === ',') {
  5130. warning("Extra comma.");
  5131. advance(',');
  5132. }
  5133. if (nexttoken.id === ']') {
  5134. break;
  5135. }
  5136. if (b && token.line !== nexttoken.line) {
  5137. indentation();
  5138. }
  5139. this.first.push(expression(10));
  5140. if (nexttoken.id === ',') {
  5141. comma();
  5142. if (nexttoken.id === ']' && !option.es5) {
  5143. warning("Extra comma.", token);
  5144. break;
  5145. }
  5146. } else {
  5147. break;
  5148. }
  5149. }
  5150. if (b) {
  5151. indent -= option.indent;
  5152. indentation();
  5153. }
  5154. advance(']', this);
  5155. return this;
  5156. }, 160);
  5157. function property_name() {
  5158. var id = optionalidentifier(true);
  5159. if (!id) {
  5160. if (nexttoken.id === '(string)') {
  5161. id = nexttoken.value;
  5162. advance();
  5163. } else if (nexttoken.id === '(number)') {
  5164. id = nexttoken.value.toString();
  5165. advance();
  5166. }
  5167. }
  5168. return id;
  5169. }
  5170. function functionparams() {
  5171. var i, t = nexttoken, p = [];
  5172. advance('(');
  5173. nospace();
  5174. if (nexttoken.id === ')') {
  5175. advance(')');
  5176. return;
  5177. }
  5178. for (;;) {
  5179. i = identifier(true);
  5180. p.push(i);
  5181. addlabel(i, 'parameter');
  5182. if (nexttoken.id === ',') {
  5183. comma();
  5184. } else {
  5185. advance(')', t);
  5186. nospace(prevtoken, token);
  5187. return p;
  5188. }
  5189. }
  5190. }
  5191. function doFunction(i, statement) {
  5192. var f,
  5193. oldOption = option,
  5194. oldScope = scope;
  5195. option = Object.create(option);
  5196. scope = Object.create(scope);
  5197. funct = {
  5198. '(name)' : i || '"' + anonname + '"',
  5199. '(line)' : nexttoken.line,
  5200. '(context)' : funct,
  5201. '(breakage)' : 0,
  5202. '(loopage)' : 0,
  5203. '(scope)' : scope,
  5204. '(statement)': statement
  5205. };
  5206. f = funct;
  5207. token.funct = funct;
  5208. functions.push(funct);
  5209. if (i) {
  5210. addlabel(i, 'function');
  5211. }
  5212. funct['(params)'] = functionparams();
  5213. block(false, false, true);
  5214. scope = oldScope;
  5215. option = oldOption;
  5216. funct['(last)'] = token.line;
  5217. funct = funct['(context)'];
  5218. return f;
  5219. }
  5220. (function (x) {
  5221. x.nud = function () {
  5222. var b, f, i, j, p, t;
  5223. var props = {}; // All properties, including accessors
  5224. function saveProperty(name, token) {
  5225. if (props[name] && is_own(props, name))
  5226. warning("Duplicate member '{a}'.", nexttoken, i);
  5227. else
  5228. props[name] = {};
  5229. props[name].basic = true;
  5230. props[name].basicToken = token;
  5231. }
  5232. function saveSetter(name, token) {
  5233. if (props[name] && is_own(props, name)) {
  5234. if (props[name].basic || props[name].setter)
  5235. warning("Duplicate member '{a}'.", nexttoken, i);
  5236. } else {
  5237. props[name] = {};
  5238. }
  5239. props[name].setter = true;
  5240. props[name].setterToken = token;
  5241. }
  5242. function saveGetter(name) {
  5243. if (props[name] && is_own(props, name)) {
  5244. if (props[name].basic || props[name].getter)
  5245. warning("Duplicate member '{a}'.", nexttoken, i);
  5246. } else {
  5247. props[name] = {};
  5248. }
  5249. props[name].getter = true;
  5250. props[name].getterToken = token;
  5251. }
  5252. b = token.line !== nexttoken.line;
  5253. if (b) {
  5254. indent += option.indent;
  5255. if (nexttoken.from === indent + option.indent) {
  5256. indent += option.indent;
  5257. }
  5258. }
  5259. for (;;) {
  5260. if (nexttoken.id === '}') {
  5261. break;
  5262. }
  5263. if (b) {
  5264. indentation();
  5265. }
  5266. if (nexttoken.value === 'get' && peek().id !== ':') {
  5267. advance('get');
  5268. if (!option.es5) {
  5269. error("get/set are ES5 features.");
  5270. }
  5271. i = property_name();
  5272. if (!i) {
  5273. error("Missing property name.");
  5274. }
  5275. saveGetter(i);
  5276. t = nexttoken;
  5277. adjacent(token, nexttoken);
  5278. f = doFunction();
  5279. p = f['(params)'];
  5280. if (p) {
  5281. warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i);
  5282. }
  5283. adjacent(token, nexttoken);
  5284. } else if (nexttoken.value === 'set' && peek().id !== ':') {
  5285. advance('set');
  5286. if (!option.es5) {
  5287. error("get/set are ES5 features.");
  5288. }
  5289. i = property_name();
  5290. if (!i) {
  5291. error("Missing property name.");
  5292. }
  5293. saveSetter(i, nexttoken);
  5294. t = nexttoken;
  5295. adjacent(token, nexttoken);
  5296. f = doFunction();
  5297. p = f['(params)'];
  5298. if (!p || p.length !== 1) {
  5299. warning("Expected a single parameter in set {a} function.", t, i);
  5300. }
  5301. } else {
  5302. i = property_name();
  5303. saveProperty(i, nexttoken);
  5304. if (typeof i !== 'string') {
  5305. break;
  5306. }
  5307. advance(':');
  5308. nonadjacent(token, nexttoken);
  5309. expression(10);
  5310. }
  5311. countMember(i);
  5312. if (nexttoken.id === ',') {
  5313. comma();
  5314. if (nexttoken.id === ',') {
  5315. warning("Extra comma.", token);
  5316. } else if (nexttoken.id === '}' && !option.es5) {
  5317. warning("Extra comma.", token);
  5318. }
  5319. } else {
  5320. break;
  5321. }
  5322. }
  5323. if (b) {
  5324. indent -= option.indent;
  5325. indentation();
  5326. }
  5327. advance('}', this);
  5328. // Check for lonely setters if in the ES5 mode.
  5329. if (option.es5) {
  5330. for (var name in props) {
  5331. if (is_own(props, name) && props[name].setter && !props[name].getter) {
  5332. warning("Setter is defined without getter.", props[name].setterToken);
  5333. }
  5334. }
  5335. }
  5336. return this;
  5337. };
  5338. x.fud = function () {
  5339. error("Expected to see a statement and instead saw a block.", token);
  5340. };
  5341. }(delim('{')));
  5342. // This Function is called when esnext option is set to true
  5343. // it adds the `const` statement to JSHINT
  5344. useESNextSyntax = function () {
  5345. var conststatement = stmt('const', function (prefix) {
  5346. var id, name, value;
  5347. this.first = [];
  5348. for (;;) {
  5349. nonadjacent(token, nexttoken);
  5350. id = identifier();
  5351. if (funct[id] === "const") {
  5352. warning("const '" + id + "' has already been declared");
  5353. }
  5354. if (funct['(global)'] && predefined[id] === false) {
  5355. warning("Redefinition of '{a}'.", token, id);
  5356. }
  5357. addlabel(id, 'const');
  5358. if (prefix) {
  5359. break;
  5360. }
  5361. name = token;
  5362. this.first.push(token);
  5363. if (nexttoken.id !== "=") {
  5364. warning("const " +
  5365. "'{a}' is initialized to 'undefined'.", token, id);
  5366. }
  5367. if (nexttoken.id === '=') {
  5368. nonadjacent(token, nexttoken);
  5369. advance('=');
  5370. nonadjacent(token, nexttoken);
  5371. if (nexttoken.id === 'undefined') {
  5372. warning("It is not necessary to initialize " +
  5373. "'{a}' to 'undefined'.", token, id);
  5374. }
  5375. if (peek(0).id === '=' && nexttoken.identifier) {
  5376. error("Constant {a} was not declared correctly.",
  5377. nexttoken, nexttoken.value);
  5378. }
  5379. value = expression(0);
  5380. name.first = value;
  5381. }
  5382. if (nexttoken.id !== ',') {
  5383. break;
  5384. }
  5385. comma();
  5386. }
  5387. return this;
  5388. });
  5389. conststatement.exps = true;
  5390. };
  5391. var varstatement = stmt('var', function (prefix) {
  5392. // JavaScript does not have block scope. It only has function scope. So,
  5393. // declaring a variable in a block can have unexpected consequences.
  5394. var id, name, value;
  5395. if (funct['(onevar)'] && option.onevar) {
  5396. warning("Too many var statements.");
  5397. } else if (!funct['(global)']) {
  5398. funct['(onevar)'] = true;
  5399. }
  5400. this.first = [];
  5401. for (;;) {
  5402. nonadjacent(token, nexttoken);
  5403. id = identifier();
  5404. if (option.esnext && funct[id] === "const") {
  5405. warning("const '" + id + "' has already been declared");
  5406. }
  5407. if (funct['(global)'] && predefined[id] === false) {
  5408. warning("Redefinition of '{a}'.", token, id);
  5409. }
  5410. addlabel(id, 'unused');
  5411. if (prefix) {
  5412. break;
  5413. }
  5414. name = token;
  5415. this.first.push(token);
  5416. if (nexttoken.id === '=') {
  5417. nonadjacent(token, nexttoken);
  5418. advance('=');
  5419. nonadjacent(token, nexttoken);
  5420. if (nexttoken.id === 'undefined') {
  5421. warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id);
  5422. }
  5423. if (peek(0).id === '=' && nexttoken.identifier) {
  5424. error("Variable {a} was not declared correctly.",
  5425. nexttoken, nexttoken.value);
  5426. }
  5427. value = expression(0);
  5428. name.first = value;
  5429. }
  5430. if (nexttoken.id !== ',') {
  5431. break;
  5432. }
  5433. comma();
  5434. }
  5435. return this;
  5436. });
  5437. varstatement.exps = true;
  5438. blockstmt('function', function () {
  5439. if (inblock) {
  5440. warning("Function declarations should not be placed in blocks. " +
  5441. "Use a function expression or move the statement to the top of " +
  5442. "the outer function.", token);
  5443. }
  5444. var i = identifier();
  5445. if (option.esnext && funct[i] === "const") {
  5446. warning("const '" + i + "' has already been declared");
  5447. }
  5448. adjacent(token, nexttoken);
  5449. addlabel(i, 'unction');
  5450. doFunction(i, true);
  5451. if (nexttoken.id === '(' && nexttoken.line === token.line) {
  5452. error(
  5453. "Function declarations are not invocable. Wrap the whole function invocation in parens.");
  5454. }
  5455. return this;
  5456. });
  5457. prefix('function', function () {
  5458. var i = optionalidentifier();
  5459. if (i) {
  5460. adjacent(token, nexttoken);
  5461. } else {
  5462. nonadjacent(token, nexttoken);
  5463. }
  5464. doFunction(i);
  5465. if (!option.loopfunc && funct['(loopage)']) {
  5466. warning("Don't make functions within a loop.");
  5467. }
  5468. return this;
  5469. });
  5470. blockstmt('if', function () {
  5471. var t = nexttoken;
  5472. advance('(');
  5473. nonadjacent(this, t);
  5474. nospace();
  5475. expression(20);
  5476. if (nexttoken.id === '=') {
  5477. if (!option.boss)
  5478. warning("Expected a conditional expression and instead saw an assignment.");
  5479. advance('=');
  5480. expression(20);
  5481. }
  5482. advance(')', t);
  5483. nospace(prevtoken, token);
  5484. block(true, true);
  5485. if (nexttoken.id === 'else') {
  5486. nonadjacent(token, nexttoken);
  5487. advance('else');
  5488. if (nexttoken.id === 'if' || nexttoken.id === 'switch') {
  5489. statement(true);
  5490. } else {
  5491. block(true, true);
  5492. }
  5493. }
  5494. return this;
  5495. });
  5496. blockstmt('try', function () {
  5497. var b, e, s;
  5498. block(false);
  5499. if (nexttoken.id === 'catch') {
  5500. advance('catch');
  5501. nonadjacent(token, nexttoken);
  5502. advance('(');
  5503. s = scope;
  5504. scope = Object.create(s);
  5505. e = nexttoken.value;
  5506. if (nexttoken.type !== '(identifier)') {
  5507. warning("Expected an identifier and instead saw '{a}'.",
  5508. nexttoken, e);
  5509. } else {
  5510. addlabel(e, 'exception');
  5511. }
  5512. advance();
  5513. advance(')');
  5514. block(false);
  5515. b = true;
  5516. scope = s;
  5517. }
  5518. if (nexttoken.id === 'finally') {
  5519. advance('finally');
  5520. block(false);
  5521. return;
  5522. } else if (!b) {
  5523. error("Expected '{a}' and instead saw '{b}'.",
  5524. nexttoken, 'catch', nexttoken.value);
  5525. }
  5526. return this;
  5527. });
  5528. blockstmt('while', function () {
  5529. var t = nexttoken;
  5530. funct['(breakage)'] += 1;
  5531. funct['(loopage)'] += 1;
  5532. advance('(');
  5533. nonadjacent(this, t);
  5534. nospace();
  5535. expression(20);
  5536. if (nexttoken.id === '=') {
  5537. if (!option.boss)
  5538. warning("Expected a conditional expression and instead saw an assignment.");
  5539. advance('=');
  5540. expression(20);
  5541. }
  5542. advance(')', t);
  5543. nospace(prevtoken, token);
  5544. block(true, true);
  5545. funct['(breakage)'] -= 1;
  5546. funct['(loopage)'] -= 1;
  5547. return this;
  5548. }).labelled = true;
  5549. blockstmt('with', function () {
  5550. var t = nexttoken;
  5551. if (directive['use strict']) {
  5552. error("'with' is not allowed in strict mode.", token);
  5553. } else if (!option.withstmt) {
  5554. warning("Don't use 'with'.", token);
  5555. }
  5556. advance('(');
  5557. nonadjacent(this, t);
  5558. nospace();
  5559. expression(0);
  5560. advance(')', t);
  5561. nospace(prevtoken, token);
  5562. block(true, true);
  5563. return this;
  5564. });
  5565. blockstmt('switch', function () {
  5566. var t = nexttoken,
  5567. g = false;
  5568. funct['(breakage)'] += 1;
  5569. advance('(');
  5570. nonadjacent(this, t);
  5571. nospace();
  5572. this.condition = expression(20);
  5573. advance(')', t);
  5574. nospace(prevtoken, token);
  5575. nonadjacent(token, nexttoken);
  5576. t = nexttoken;
  5577. advance('{');
  5578. nonadjacent(token, nexttoken);
  5579. indent += option.indent;
  5580. this.cases = [];
  5581. for (;;) {
  5582. switch (nexttoken.id) {
  5583. case 'case':
  5584. switch (funct['(verb)']) {
  5585. case 'break':
  5586. case 'case':
  5587. case 'continue':
  5588. case 'return':
  5589. case 'switch':
  5590. case 'throw':
  5591. break;
  5592. default:
  5593. // You can tell JSHint that you don't use break intentionally by
  5594. // adding a comment /* falls through */ on a line just before
  5595. // the next `case`.
  5596. if (!ft.test(lines[nexttoken.line - 2])) {
  5597. warning(
  5598. "Expected a 'break' statement before 'case'.",
  5599. token);
  5600. }
  5601. }
  5602. indentation(-option.indent);
  5603. advance('case');
  5604. this.cases.push(expression(20));
  5605. g = true;
  5606. advance(':');
  5607. funct['(verb)'] = 'case';
  5608. break;
  5609. case 'default':
  5610. switch (funct['(verb)']) {
  5611. case 'break':
  5612. case 'continue':
  5613. case 'return':
  5614. case 'throw':
  5615. break;
  5616. default:
  5617. if (!ft.test(lines[nexttoken.line - 2])) {
  5618. warning(
  5619. "Expected a 'break' statement before 'default'.",
  5620. token);
  5621. }
  5622. }
  5623. indentation(-option.indent);
  5624. advance('default');
  5625. g = true;
  5626. advance(':');
  5627. break;
  5628. case '}':
  5629. indent -= option.indent;
  5630. indentation();
  5631. advance('}', t);
  5632. if (this.cases.length === 1 || this.condition.id === 'true' ||
  5633. this.condition.id === 'false') {
  5634. if (!option.onecase)
  5635. warning("This 'switch' should be an 'if'.", this);
  5636. }
  5637. funct['(breakage)'] -= 1;
  5638. funct['(verb)'] = undefined;
  5639. return;
  5640. case '(end)':
  5641. error("Missing '{a}'.", nexttoken, '}');
  5642. return;
  5643. default:
  5644. if (g) {
  5645. switch (token.id) {
  5646. case ',':
  5647. error("Each value should have its own case label.");
  5648. return;
  5649. case ':':
  5650. g = false;
  5651. statements();
  5652. break;
  5653. default:
  5654. error("Missing ':' on a case clause.", token);
  5655. return;
  5656. }
  5657. } else {
  5658. if (token.id === ':') {
  5659. advance(':');
  5660. error("Unexpected '{a}'.", token, ':');
  5661. statements();
  5662. } else {
  5663. error("Expected '{a}' and instead saw '{b}'.",
  5664. nexttoken, 'case', nexttoken.value);
  5665. return;
  5666. }
  5667. }
  5668. }
  5669. }
  5670. }).labelled = true;
  5671. stmt('debugger', function () {
  5672. if (!option.debug) {
  5673. warning("All 'debugger' statements should be removed.");
  5674. }
  5675. return this;
  5676. }).exps = true;
  5677. (function () {
  5678. var x = stmt('do', function () {
  5679. funct['(breakage)'] += 1;
  5680. funct['(loopage)'] += 1;
  5681. this.first = block(true);
  5682. advance('while');
  5683. var t = nexttoken;
  5684. nonadjacent(token, t);
  5685. advance('(');
  5686. nospace();
  5687. expression(20);
  5688. if (nexttoken.id === '=') {
  5689. if (!option.boss)
  5690. warning("Expected a conditional expression and instead saw an assignment.");
  5691. advance('=');
  5692. expression(20);
  5693. }
  5694. advance(')', t);
  5695. nospace(prevtoken, token);
  5696. funct['(breakage)'] -= 1;
  5697. funct['(loopage)'] -= 1;
  5698. return this;
  5699. });
  5700. x.labelled = true;
  5701. x.exps = true;
  5702. }());
  5703. blockstmt('for', function () {
  5704. var s, t = nexttoken;
  5705. funct['(breakage)'] += 1;
  5706. funct['(loopage)'] += 1;
  5707. advance('(');
  5708. nonadjacent(this, t);
  5709. nospace();
  5710. if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {
  5711. if (nexttoken.id === 'var') {
  5712. advance('var');
  5713. varstatement.fud.call(varstatement, true);
  5714. } else {
  5715. switch (funct[nexttoken.value]) {
  5716. case 'unused':
  5717. funct[nexttoken.value] = 'var';
  5718. break;
  5719. case 'var':
  5720. break;
  5721. default:
  5722. warning("Bad for in variable '{a}'.",
  5723. nexttoken, nexttoken.value);
  5724. }
  5725. advance();
  5726. }
  5727. advance('in');
  5728. expression(20);
  5729. advance(')', t);
  5730. s = block(true, true);
  5731. if (option.forin && s && (s.length > 1 || typeof s[0] !== 'object' ||
  5732. s[0].value !== 'if')) {
  5733. warning("The body of a for in should be wrapped in an if statement to filter " +
  5734. "unwanted properties from the prototype.", this);
  5735. }
  5736. funct['(breakage)'] -= 1;
  5737. funct['(loopage)'] -= 1;
  5738. return this;
  5739. } else {
  5740. if (nexttoken.id !== ';') {
  5741. if (nexttoken.id === 'var') {
  5742. advance('var');
  5743. varstatement.fud.call(varstatement);
  5744. } else {
  5745. for (;;) {
  5746. expression(0, 'for');
  5747. if (nexttoken.id !== ',') {
  5748. break;
  5749. }
  5750. comma();
  5751. }
  5752. }
  5753. }
  5754. nolinebreak(token);
  5755. advance(';');
  5756. if (nexttoken.id !== ';') {
  5757. expression(20);
  5758. if (nexttoken.id === '=') {
  5759. if (!option.boss)
  5760. warning("Expected a conditional expression and instead saw an assignment.");
  5761. advance('=');
  5762. expression(20);
  5763. }
  5764. }
  5765. nolinebreak(token);
  5766. advance(';');
  5767. if (nexttoken.id === ';') {
  5768. error("Expected '{a}' and instead saw '{b}'.",
  5769. nexttoken, ')', ';');
  5770. }
  5771. if (nexttoken.id !== ')') {
  5772. for (;;) {
  5773. expression(0, 'for');
  5774. if (nexttoken.id !== ',') {
  5775. break;
  5776. }
  5777. comma();
  5778. }
  5779. }
  5780. advance(')', t);
  5781. nospace(prevtoken, token);
  5782. block(true, true);
  5783. funct['(breakage)'] -= 1;
  5784. funct['(loopage)'] -= 1;
  5785. return this;
  5786. }
  5787. }).labelled = true;
  5788. stmt('break', function () {
  5789. var v = nexttoken.value;
  5790. if (funct['(breakage)'] === 0)
  5791. warning("Unexpected '{a}'.", nexttoken, this.value);
  5792. if (!option.asi)
  5793. nolinebreak(this);
  5794. if (nexttoken.id !== ';') {
  5795. if (token.line === nexttoken.line) {
  5796. if (funct[v] !== 'label') {
  5797. warning("'{a}' is not a statement label.", nexttoken, v);
  5798. } else if (scope[v] !== funct) {
  5799. warning("'{a}' is out of scope.", nexttoken, v);
  5800. }
  5801. this.first = nexttoken;
  5802. advance();
  5803. }
  5804. }
  5805. reachable('break');
  5806. return this;
  5807. }).exps = true;
  5808. stmt('continue', function () {
  5809. var v = nexttoken.value;
  5810. if (funct['(breakage)'] === 0)
  5811. warning("Unexpected '{a}'.", nexttoken, this.value);
  5812. if (!option.asi)
  5813. nolinebreak(this);
  5814. if (nexttoken.id !== ';') {
  5815. if (token.line === nexttoken.line) {
  5816. if (funct[v] !== 'label') {
  5817. warning("'{a}' is not a statement label.", nexttoken, v);
  5818. } else if (scope[v] !== funct) {
  5819. warning("'{a}' is out of scope.", nexttoken, v);
  5820. }
  5821. this.first = nexttoken;
  5822. advance();
  5823. }
  5824. } else if (!funct['(loopage)']) {
  5825. warning("Unexpected '{a}'.", nexttoken, this.value);
  5826. }
  5827. reachable('continue');
  5828. return this;
  5829. }).exps = true;
  5830. stmt('return', function () {
  5831. if (this.line === nexttoken.line) {
  5832. if (nexttoken.id === '(regexp)')
  5833. warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");
  5834. if (nexttoken.id !== ';' && !nexttoken.reach) {
  5835. nonadjacent(token, nexttoken);
  5836. if (peek().value === "=" && !option.boss) {
  5837. warningAt("Did you mean to return a conditional instead of an assignment?",
  5838. token.line, token.character + 1);
  5839. }
  5840. this.first = expression(0);
  5841. }
  5842. } else if (!option.asi) {
  5843. nolinebreak(this); // always warn (Line breaking error)
  5844. }
  5845. reachable('return');
  5846. return this;
  5847. }).exps = true;
  5848. stmt('throw', function () {
  5849. nolinebreak(this);
  5850. nonadjacent(token, nexttoken);
  5851. this.first = expression(20);
  5852. reachable('throw');
  5853. return this;
  5854. }).exps = true;
  5855. // Superfluous reserved words
  5856. reserve('class');
  5857. reserve('const');
  5858. reserve('enum');
  5859. reserve('export');
  5860. reserve('extends');
  5861. reserve('import');
  5862. reserve('super');
  5863. reserve('let');
  5864. reserve('yield');
  5865. reserve('implements');
  5866. reserve('interface');
  5867. reserve('package');
  5868. reserve('private');
  5869. reserve('protected');
  5870. reserve('public');
  5871. reserve('static');
  5872. // Parse JSON
  5873. function jsonValue() {
  5874. function jsonObject() {
  5875. var o = {}, t = nexttoken;
  5876. advance('{');
  5877. if (nexttoken.id !== '}') {
  5878. for (;;) {
  5879. if (nexttoken.id === '(end)') {
  5880. error("Missing '}' to match '{' from line {a}.",
  5881. nexttoken, t.line);
  5882. } else if (nexttoken.id === '}') {
  5883. warning("Unexpected comma.", token);
  5884. break;
  5885. } else if (nexttoken.id === ',') {
  5886. error("Unexpected comma.", nexttoken);
  5887. } else if (nexttoken.id !== '(string)') {
  5888. warning("Expected a string and instead saw {a}.",
  5889. nexttoken, nexttoken.value);
  5890. }
  5891. if (o[nexttoken.value] === true) {
  5892. warning("Duplicate key '{a}'.",
  5893. nexttoken, nexttoken.value);
  5894. } else if ((nexttoken.value === '__proto__' &&
  5895. !option.proto) || (nexttoken.value === '__iterator__' &&
  5896. !option.iterator)) {
  5897. warning("The '{a}' key may produce unexpected results.",
  5898. nexttoken, nexttoken.value);
  5899. } else {
  5900. o[nexttoken.value] = true;
  5901. }
  5902. advance();
  5903. advance(':');
  5904. jsonValue();
  5905. if (nexttoken.id !== ',') {
  5906. break;
  5907. }
  5908. advance(',');
  5909. }
  5910. }
  5911. advance('}');
  5912. }
  5913. function jsonArray() {
  5914. var t = nexttoken;
  5915. advance('[');
  5916. if (nexttoken.id !== ']') {
  5917. for (;;) {
  5918. if (nexttoken.id === '(end)') {
  5919. error("Missing ']' to match '[' from line {a}.",
  5920. nexttoken, t.line);
  5921. } else if (nexttoken.id === ']') {
  5922. warning("Unexpected comma.", token);
  5923. break;
  5924. } else if (nexttoken.id === ',') {
  5925. error("Unexpected comma.", nexttoken);
  5926. }
  5927. jsonValue();
  5928. if (nexttoken.id !== ',') {
  5929. break;
  5930. }
  5931. advance(',');
  5932. }
  5933. }
  5934. advance(']');
  5935. }
  5936. switch (nexttoken.id) {
  5937. case '{':
  5938. jsonObject();
  5939. break;
  5940. case '[':
  5941. jsonArray();
  5942. break;
  5943. case 'true':
  5944. case 'false':
  5945. case 'null':
  5946. case '(number)':
  5947. case '(string)':
  5948. advance();
  5949. break;
  5950. case '-':
  5951. advance('-');
  5952. if (token.character !== nexttoken.from) {
  5953. warning("Unexpected space after '-'.", token);
  5954. }
  5955. adjacent(token, nexttoken);
  5956. advance('(number)');
  5957. break;
  5958. default:
  5959. error("Expected a JSON value.", nexttoken);
  5960. }
  5961. }
  5962. // The actual JSHINT function itself.
  5963. var itself = function (s, o, g) {
  5964. var a, i, k;
  5965. JSHINT.errors = [];
  5966. JSHINT.undefs = [];
  5967. predefined = Object.create(standard);
  5968. combine(predefined, g || {});
  5969. if (o) {
  5970. a = o.predef;
  5971. if (a) {
  5972. if (Array.isArray(a)) {
  5973. for (i = 0; i < a.length; i += 1) {
  5974. predefined[a[i]] = true;
  5975. }
  5976. } else if (typeof a === 'object') {
  5977. k = Object.keys(a);
  5978. for (i = 0; i < k.length; i += 1) {
  5979. predefined[k[i]] = !!a[k[i]];
  5980. }
  5981. }
  5982. }
  5983. option = o;
  5984. } else {
  5985. option = {};
  5986. }
  5987. option.indent = option.indent || 4;
  5988. option.maxerr = option.maxerr || 50;
  5989. tab = '';
  5990. for (i = 0; i < option.indent; i += 1) {
  5991. tab += ' ';
  5992. }
  5993. indent = 1;
  5994. global = Object.create(predefined);
  5995. scope = global;
  5996. funct = {
  5997. '(global)': true,
  5998. '(name)': '(global)',
  5999. '(scope)': scope,
  6000. '(breakage)': 0,
  6001. '(loopage)': 0
  6002. };
  6003. functions = [funct];
  6004. urls = [];
  6005. stack = null;
  6006. member = {};
  6007. membersOnly = null;
  6008. implied = {};
  6009. inblock = false;
  6010. lookahead = [];
  6011. jsonmode = false;
  6012. warnings = 0;
  6013. lex.init(s);
  6014. prereg = true;
  6015. directive = {};
  6016. prevtoken = token = nexttoken = syntax['(begin)'];
  6017. // Check options
  6018. for (var name in o) {
  6019. if (is_own(o, name)) {
  6020. checkOption(name, token);
  6021. }
  6022. }
  6023. assume();
  6024. // combine the passed globals after we've assumed all our options
  6025. combine(predefined, g || {});
  6026. //reset values
  6027. comma.first = true;
  6028. try {
  6029. advance();
  6030. switch (nexttoken.id) {
  6031. case '{':
  6032. case '[':
  6033. option.laxbreak = true;
  6034. jsonmode = true;
  6035. jsonValue();
  6036. break;
  6037. default:
  6038. directives();
  6039. if (directive["use strict"] && !option.globalstrict) {
  6040. warning("Use the function form of \"use strict\".", prevtoken);
  6041. }
  6042. statements();
  6043. }
  6044. advance('(end)');
  6045. var markDefined = function (name, context) {
  6046. do {
  6047. if (typeof context[name] === 'string') {
  6048. // JSHINT marks unused variables as 'unused' and
  6049. // unused function declaration as 'unction'. This
  6050. // code changes such instances back 'var' and
  6051. // 'closure' so that the code in JSHINT.data()
  6052. // doesn't think they're unused.
  6053. if (context[name] === 'unused')
  6054. context[name] = 'var';
  6055. else if (context[name] === 'unction')
  6056. context[name] = 'closure';
  6057. return true;
  6058. }
  6059. context = context['(context)'];
  6060. } while (context);
  6061. return false;
  6062. };
  6063. var clearImplied = function (name, line) {
  6064. if (!implied[name])
  6065. return;
  6066. var newImplied = [];
  6067. for (var i = 0; i < implied[name].length; i += 1) {
  6068. if (implied[name][i] !== line)
  6069. newImplied.push(implied[name][i]);
  6070. }
  6071. if (newImplied.length === 0)
  6072. delete implied[name];
  6073. else
  6074. implied[name] = newImplied;
  6075. };
  6076. // Check queued 'x is not defined' instances to see if they're still undefined.
  6077. for (i = 0; i < JSHINT.undefs.length; i += 1) {
  6078. k = JSHINT.undefs[i].slice(0);
  6079. if (markDefined(k[2].value, k[0])) {
  6080. clearImplied(k[2].value, k[2].line);
  6081. } else {
  6082. warning.apply(warning, k.slice(1));
  6083. }
  6084. }
  6085. } catch (e) {
  6086. if (e) {
  6087. var nt = nexttoken || {};
  6088. JSHINT.errors.push({
  6089. raw : e.raw,
  6090. reason : e.message,
  6091. line : e.line || nt.line,
  6092. character : e.character || nt.from
  6093. }, null);
  6094. }
  6095. }
  6096. return JSHINT.errors.length === 0;
  6097. };
  6098. // Data summary.
  6099. itself.data = function () {
  6100. var data = { functions: [], options: option }, fu, globals, implieds = [], f, i, j,
  6101. members = [], n, unused = [], v;
  6102. if (itself.errors.length) {
  6103. data.errors = itself.errors;
  6104. }
  6105. if (jsonmode) {
  6106. data.json = true;
  6107. }
  6108. for (n in implied) {
  6109. if (is_own(implied, n)) {
  6110. implieds.push({
  6111. name: n,
  6112. line: implied[n]
  6113. });
  6114. }
  6115. }
  6116. if (implieds.length > 0) {
  6117. data.implieds = implieds;
  6118. }
  6119. if (urls.length > 0) {
  6120. data.urls = urls;
  6121. }
  6122. globals = Object.keys(scope);
  6123. if (globals.length > 0) {
  6124. data.globals = globals;
  6125. }
  6126. for (i = 1; i < functions.length; i += 1) {
  6127. f = functions[i];
  6128. fu = {};
  6129. for (j = 0; j < functionicity.length; j += 1) {
  6130. fu[functionicity[j]] = [];
  6131. }
  6132. for (n in f) {
  6133. if (is_own(f, n) && n.charAt(0) !== '(') {
  6134. v = f[n];
  6135. if (v === 'unction') {
  6136. v = 'unused';
  6137. }
  6138. if (Array.isArray(fu[v])) {
  6139. fu[v].push(n);
  6140. if (v === 'unused') {
  6141. unused.push({
  6142. name: n,
  6143. line: f['(line)'],
  6144. 'function': f['(name)']
  6145. });
  6146. }
  6147. }
  6148. }
  6149. }
  6150. for (j = 0; j < functionicity.length; j += 1) {
  6151. if (fu[functionicity[j]].length === 0) {
  6152. delete fu[functionicity[j]];
  6153. }
  6154. }
  6155. fu.name = f['(name)'];
  6156. fu.param = f['(params)'];
  6157. fu.line = f['(line)'];
  6158. fu.last = f['(last)'];
  6159. data.functions.push(fu);
  6160. }
  6161. if (unused.length > 0) {
  6162. data.unused = unused;
  6163. }
  6164. members = [];
  6165. for (n in member) {
  6166. if (typeof member[n] === 'number') {
  6167. data.member = member;
  6168. break;
  6169. }
  6170. }
  6171. return data;
  6172. };
  6173. itself.report = function (option) {
  6174. var data = itself.data();
  6175. var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s;
  6176. function detail(h, array) {
  6177. var b, i, singularity;
  6178. if (array) {
  6179. o.push('<div><i>' + h + '</i> ');
  6180. array = array.sort();
  6181. for (i = 0; i < array.length; i += 1) {
  6182. if (array[i] !== singularity) {
  6183. singularity = array[i];
  6184. o.push((b ? ', ' : '') + singularity);
  6185. b = true;
  6186. }
  6187. }
  6188. o.push('</div>');
  6189. }
  6190. }
  6191. if (data.errors || data.implieds || data.unused) {
  6192. err = true;
  6193. o.push('<div id=errors><i>Error:</i>');
  6194. if (data.errors) {
  6195. for (i = 0; i < data.errors.length; i += 1) {
  6196. c = data.errors[i];
  6197. if (c) {
  6198. e = c.evidence || '';
  6199. o.push('<p>Problem' + (isFinite(c.line) ? ' at line ' +
  6200. c.line + ' character ' + c.character : '') +
  6201. ': ' + c.reason.entityify() +
  6202. '</p><p class=evidence>' +
  6203. (e && (e.length > 80 ? e.slice(0, 77) + '...' :
  6204. e).entityify()) + '</p>');
  6205. }
  6206. }
  6207. }
  6208. if (data.implieds) {
  6209. s = [];
  6210. for (i = 0; i < data.implieds.length; i += 1) {
  6211. s[i] = '<code>' + data.implieds[i].name + '</code>&nbsp;<i>' +
  6212. data.implieds[i].line + '</i>';
  6213. }
  6214. o.push('<p><i>Implied global:</i> ' + s.join(', ') + '</p>');
  6215. }
  6216. if (data.unused) {
  6217. s = [];
  6218. for (i = 0; i < data.unused.length; i += 1) {
  6219. s[i] = '<code><u>' + data.unused[i].name + '</u></code>&nbsp;<i>' +
  6220. data.unused[i].line + '</i> <code>' +
  6221. data.unused[i]['function'] + '</code>';
  6222. }
  6223. o.push('<p><i>Unused variable:</i> ' + s.join(', ') + '</p>');
  6224. }
  6225. if (data.json) {
  6226. o.push('<p>JSON: bad.</p>');
  6227. }
  6228. o.push('</div>');
  6229. }
  6230. if (!option) {
  6231. o.push('<br><div id=functions>');
  6232. if (data.urls) {
  6233. detail("URLs<br>", data.urls, '<br>');
  6234. }
  6235. if (data.json && !err) {
  6236. o.push('<p>JSON: good.</p>');
  6237. } else if (data.globals) {
  6238. o.push('<div><i>Global</i> ' +
  6239. data.globals.sort().join(', ') + '</div>');
  6240. } else {
  6241. o.push('<div><i>No new global variables introduced.</i></div>');
  6242. }
  6243. for (i = 0; i < data.functions.length; i += 1) {
  6244. f = data.functions[i];
  6245. o.push('<br><div class=function><i>' + f.line + '-' +
  6246. f.last + '</i> ' + (f.name || '') + '(' +
  6247. (f.param ? f.param.join(', ') : '') + ')</div>');
  6248. detail('<big><b>Unused</b></big>', f.unused);
  6249. detail('Closure', f.closure);
  6250. detail('Variable', f['var']);
  6251. detail('Exception', f.exception);
  6252. detail('Outer', f.outer);
  6253. detail('Global', f.global);
  6254. detail('Label', f.label);
  6255. }
  6256. if (data.member) {
  6257. a = Object.keys(data.member);
  6258. if (a.length) {
  6259. a = a.sort();
  6260. m = '<br><pre id=members>/*members ';
  6261. l = 10;
  6262. for (i = 0; i < a.length; i += 1) {
  6263. k = a[i];
  6264. n = k.name();
  6265. if (l + n.length > 72) {
  6266. o.push(m + '<br>');
  6267. m = ' ';
  6268. l = 1;
  6269. }
  6270. l += n.length + 2;
  6271. if (data.member[k] === 1) {
  6272. n = '<i>' + n + '</i>';
  6273. }
  6274. if (i < a.length - 1) {
  6275. n += ', ';
  6276. }
  6277. m += n;
  6278. }
  6279. o.push(m + '<br>*/</pre>');
  6280. }
  6281. o.push('</div>');
  6282. }
  6283. }
  6284. return o.join('');
  6285. };
  6286. itself.jshint = itself;
  6287. return itself;
  6288. }());
  6289. // Make JSHINT a Node module, if possible.
  6290. if (typeof exports === 'object' && exports)
  6291. exports.JSHINT = JSHINT;
  6292. });
  6293. /*
  6294. * Narcissus - JS implemented in JS.
  6295. *
  6296. * Parser.
  6297. */
  6298. define('ace/narcissus/parser', ['require', 'exports', 'module' , 'ace/narcissus/lexer', 'ace/narcissus/definitions', 'ace/narcissus/options'], function(require, exports, module) {
  6299. var lexer = require('./lexer');
  6300. var definitions = require('./definitions');
  6301. var options = require('./options');
  6302. var Tokenizer = lexer.Tokenizer;
  6303. var Dict = definitions.Dict;
  6304. var Stack = definitions.Stack;
  6305. // Set constants in the local scope.
  6306. eval(definitions.consts);
  6307. function pushDestructuringVarDecls(n, s) {
  6308. for (var i in n) {
  6309. var sub = n[i];
  6310. if (sub.type === IDENTIFIER) {
  6311. s.varDecls.push(sub);
  6312. } else {
  6313. pushDestructuringVarDecls(sub, s);
  6314. }
  6315. }
  6316. }
  6317. function Parser(tokenizer) {
  6318. tokenizer.parser = this;
  6319. this.t = tokenizer;
  6320. this.x = null;
  6321. this.unexpectedEOF = false;
  6322. options.mozillaMode && (this.mozillaMode = true);
  6323. options.parenFreeMode && (this.parenFreeMode = true);
  6324. }
  6325. function StaticContext(parentScript, parentBlock, inModule, inFunction, strictMode) {
  6326. this.parentScript = parentScript;
  6327. this.parentBlock = parentBlock || parentScript;
  6328. this.inModule = inModule || false;
  6329. this.inFunction = inFunction || false;
  6330. this.inForLoopInit = false;
  6331. this.topLevel = true;
  6332. this.allLabels = new Stack();
  6333. this.currentLabels = new Stack();
  6334. this.labeledTargets = new Stack();
  6335. this.defaultLoopTarget = null;
  6336. this.defaultTarget = null;
  6337. this.strictMode = strictMode;
  6338. }
  6339. StaticContext.prototype = {
  6340. // non-destructive update via prototype extension
  6341. update: function(ext) {
  6342. var desc = {};
  6343. for (var key in ext) {
  6344. desc[key] = {
  6345. value: ext[key],
  6346. writable: true,
  6347. enumerable: true,
  6348. configurable: true
  6349. }
  6350. }
  6351. return Object.create(this, desc);
  6352. },
  6353. pushLabel: function(label) {
  6354. return this.update({ currentLabels: this.currentLabels.push(label),
  6355. allLabels: this.allLabels.push(label) });
  6356. },
  6357. pushTarget: function(target) {
  6358. var isDefaultLoopTarget = target.isLoop;
  6359. var isDefaultTarget = isDefaultLoopTarget || target.type === SWITCH;
  6360. if (this.currentLabels.isEmpty()) {
  6361. if (isDefaultLoopTarget) this.update({ defaultLoopTarget: target });
  6362. if (isDefaultTarget) this.update({ defaultTarget: target });
  6363. return this;
  6364. }
  6365. target.labels = new Dict();
  6366. this.currentLabels.forEach(function(label) {
  6367. target.labels.set(label, true);
  6368. });
  6369. return this.update({ currentLabels: new Stack(),
  6370. labeledTargets: this.labeledTargets.push(target),
  6371. defaultLoopTarget: isDefaultLoopTarget
  6372. ? target
  6373. : this.defaultLoopTarget,
  6374. defaultTarget: isDefaultTarget
  6375. ? target
  6376. : this.defaultTarget });
  6377. },
  6378. nest: function() {
  6379. return this.topLevel ? this.update({ topLevel: false }) : this;
  6380. },
  6381. canImport: function() {
  6382. return this.topLevel && !this.inFunction;
  6383. },
  6384. canExport: function() {
  6385. return this.inModule && this.topLevel && !this.inFunction;
  6386. },
  6387. banWith: function() {
  6388. return this.strictMode || this.inModule;
  6389. },
  6390. modulesAllowed: function() {
  6391. return this.topLevel && !this.inFunction;
  6392. }
  6393. };
  6394. var Pp = Parser.prototype;
  6395. Pp.mozillaMode = false;
  6396. Pp.parenFreeMode = false;
  6397. Pp.withContext = function(x, f) {
  6398. var x0 = this.x;
  6399. this.x = x;
  6400. var result = f.call(this);
  6401. // NB: we don't bother with finally, since exceptions trash the parser
  6402. this.x = x0;
  6403. return result;
  6404. };
  6405. Pp.newNode = function newNode(opts) {
  6406. return new Node(this.t, opts);
  6407. };
  6408. Pp.fail = function fail(msg) {
  6409. throw this.t.newSyntaxError(msg);
  6410. };
  6411. Pp.match = function match(tt, scanOperand, keywordIsName) {
  6412. return this.t.match(tt, scanOperand, keywordIsName);
  6413. };
  6414. Pp.mustMatch = function mustMatch(tt, keywordIsName) {
  6415. return this.t.mustMatch(tt, keywordIsName);
  6416. };
  6417. Pp.peek = function peek(scanOperand) {
  6418. return this.t.peek(scanOperand);
  6419. };
  6420. Pp.peekOnSameLine = function peekOnSameLine(scanOperand) {
  6421. return this.t.peekOnSameLine(scanOperand);
  6422. };
  6423. Pp.done = function done() {
  6424. return this.t.done;
  6425. };
  6426. Pp.Script = function Script(inModule, inFunction, expectEnd) {
  6427. var node = this.newNode(scriptInit());
  6428. var x2 = new StaticContext(node, node, inModule, inFunction);
  6429. this.withContext(x2, function() {
  6430. this.Statements(node, true);
  6431. });
  6432. if (expectEnd && !this.done())
  6433. this.fail("expected end of input");
  6434. return node;
  6435. };
  6436. function Pragma(n) {
  6437. if (n.type === SEMICOLON) {
  6438. var e = n.expression;
  6439. if (e.type === STRING && e.value === "use strict") {
  6440. n.pragma = "strict";
  6441. return true;
  6442. }
  6443. }
  6444. return false;
  6445. }
  6446. /*
  6447. * Node :: (tokenizer, optional init object) -> node
  6448. */
  6449. function Node(t, init) {
  6450. var token = t.token;
  6451. if (token) {
  6452. // If init.type exists it will override token.type.
  6453. this.type = token.type;
  6454. this.value = token.value;
  6455. this.lineno = token.lineno;
  6456. // Start and end are file positions for error handling.
  6457. this.start = token.start;
  6458. this.end = token.end;
  6459. } else {
  6460. this.lineno = t.lineno;
  6461. }
  6462. this.filename = t.filename;
  6463. this.children = [];
  6464. for (var prop in init)
  6465. this[prop] = init[prop];
  6466. }
  6467. /*
  6468. * SyntheticNode :: (optional init object) -> node
  6469. */
  6470. function SyntheticNode(init) {
  6471. this.children = [];
  6472. for (var prop in init)
  6473. this[prop] = init[prop];
  6474. this.synthetic = true;
  6475. }
  6476. var Np = Node.prototype = SyntheticNode.prototype = {};
  6477. Np.constructor = Node;
  6478. var TO_SOURCE_SKIP = {
  6479. type: true,
  6480. value: true,
  6481. lineno: true,
  6482. start: true,
  6483. end: true,
  6484. tokenizer: true,
  6485. assignOp: true
  6486. };
  6487. function unevalableConst(code) {
  6488. var token = definitions.tokens[code];
  6489. var constName = definitions.opTypeNames.hasOwnProperty(token)
  6490. ? definitions.opTypeNames[token]
  6491. : token in definitions.keywords
  6492. ? token.toUpperCase()
  6493. : token;
  6494. return { toSource: function() { return constName } };
  6495. }
  6496. Np.toSource = function toSource() {
  6497. var mock = {};
  6498. var self = this;
  6499. mock.type = unevalableConst(this.type);
  6500. // avoid infinite recursion in case of back-links
  6501. if (this.generatingSource)
  6502. return mock.toSource();
  6503. this.generatingSource = true;
  6504. if ("value" in this)
  6505. mock.value = this.value;
  6506. if ("lineno" in this)
  6507. mock.lineno = this.lineno;
  6508. if ("start" in this)
  6509. mock.start = this.start;
  6510. if ("end" in this)
  6511. mock.end = this.end;
  6512. if (this.assignOp)
  6513. mock.assignOp = unevalableConst(this.assignOp);
  6514. for (var key in this) {
  6515. if (this.hasOwnProperty(key) && !(key in TO_SOURCE_SKIP))
  6516. mock[key] = this[key];
  6517. }
  6518. try {
  6519. return mock.toSource();
  6520. } finally {
  6521. delete this.generatingSource;
  6522. }
  6523. };
  6524. // Always use push to add operands to an expression, to update start and end.
  6525. Np.push = function (kid) {
  6526. // kid can be null e.g. [1, , 2].
  6527. if (kid !== null) {
  6528. if (kid.start < this.start)
  6529. this.start = kid.start;
  6530. if (this.end < kid.end)
  6531. this.end = kid.end;
  6532. }
  6533. return this.children.push(kid);
  6534. }
  6535. Node.indentLevel = 0;
  6536. function tokenString(tt) {
  6537. var t = definitions.tokens[tt];
  6538. return /^\W/.test(t) ? definitions.opTypeNames[t] : t.toUpperCase();
  6539. }
  6540. Np.toString = function () {
  6541. var a = [];
  6542. for (var i in this) {
  6543. if (this.hasOwnProperty(i) && i !== 'type' && i !== 'target')
  6544. a.push({id: i, value: this[i]});
  6545. }
  6546. a.sort(function (a,b) { return (a.id < b.id) ? -1 : 1; });
  6547. var INDENTATION = " ";
  6548. var n = ++Node.indentLevel;
  6549. var s = "{\n" + INDENTATION.repeat(n) + "type: " + tokenString(this.type);
  6550. for (i = 0; i < a.length; i++)
  6551. s += ",\n" + INDENTATION.repeat(n) + a[i].id + ": " + a[i].value;
  6552. n = --Node.indentLevel;
  6553. s += "\n" + INDENTATION.repeat(n) + "}";
  6554. return s;
  6555. }
  6556. Np.synth = function(init) {
  6557. var node = new SyntheticNode(init);
  6558. node.filename = this.filename;
  6559. node.lineno = this.lineno;
  6560. node.start = this.start;
  6561. node.end = this.end;
  6562. return node;
  6563. };
  6564. var LOOP_INIT = { isLoop: true };
  6565. function blockInit() {
  6566. return { type: BLOCK, varDecls: [] };
  6567. }
  6568. function scriptInit() {
  6569. return { type: SCRIPT,
  6570. funDecls: [],
  6571. varDecls: [],
  6572. modDefns: new Dict(),
  6573. modAssns: new Dict(),
  6574. modDecls: new Dict(),
  6575. modLoads: new Dict(),
  6576. impDecls: [],
  6577. expDecls: [],
  6578. exports: new Dict(),
  6579. hasEmptyReturn: false,
  6580. hasReturnWithValue: false,
  6581. hasYield: false };
  6582. }
  6583. definitions.defineGetter(Np, "length",
  6584. function() {
  6585. throw new Error("Node.prototype.length is gone; " +
  6586. "use n.children.length instead");
  6587. });
  6588. definitions.defineProperty(String.prototype, "repeat",
  6589. function(n) {
  6590. var s = "", t = this + s;
  6591. while (--n >= 0)
  6592. s += t;
  6593. return s;
  6594. }, false, false, true);
  6595. Pp.MaybeLeftParen = function MaybeLeftParen() {
  6596. if (this.parenFreeMode)
  6597. return this.match(LEFT_PAREN) ? LEFT_PAREN : END;
  6598. return this.mustMatch(LEFT_PAREN).type;
  6599. };
  6600. Pp.MaybeRightParen = function MaybeRightParen(p) {
  6601. if (p === LEFT_PAREN)
  6602. this.mustMatch(RIGHT_PAREN);
  6603. }
  6604. /*
  6605. * Statements :: (node[, boolean]) -> void
  6606. *
  6607. * Parses a sequence of Statements.
  6608. */
  6609. Pp.Statements = function Statements(n, topLevel) {
  6610. var prologue = !!topLevel;
  6611. try {
  6612. while (!this.done() && this.peek(true) !== RIGHT_CURLY) {
  6613. var n2 = this.Statement();
  6614. n.push(n2);
  6615. if (prologue && Pragma(n2)) {
  6616. this.x.strictMode = true;
  6617. n.strict = true;
  6618. } else {
  6619. prologue = false;
  6620. }
  6621. }
  6622. } catch (e) {
  6623. try {
  6624. if (this.done())
  6625. this.unexpectedEOF = true;
  6626. } catch(e) {}
  6627. throw e;
  6628. }
  6629. }
  6630. Pp.Block = function Block() {
  6631. this.mustMatch(LEFT_CURLY);
  6632. var n = this.newNode(blockInit());
  6633. var x2 = this.x.update({ parentBlock: n }).pushTarget(n);
  6634. this.withContext(x2, function() {
  6635. this.Statements(n);
  6636. });
  6637. this.mustMatch(RIGHT_CURLY);
  6638. return n;
  6639. }
  6640. var DECLARED_FORM = 0, EXPRESSED_FORM = 1, STATEMENT_FORM = 2;
  6641. function Export(node, isDefinition) {
  6642. this.node = node; // the AST node declaring this individual export
  6643. this.isDefinition = isDefinition; // is the node an 'export'-annotated definition?
  6644. this.resolved = null; // resolved pointer to the target of this export
  6645. }
  6646. /*
  6647. * registerExport :: (Dict, EXPORT node) -> void
  6648. */
  6649. function registerExport(exports, decl) {
  6650. function register(name, exp) {
  6651. if (exports.has(name))
  6652. throw new SyntaxError("multiple exports of " + name);
  6653. exports.set(name, exp);
  6654. }
  6655. switch (decl.type) {
  6656. case MODULE:
  6657. case FUNCTION:
  6658. register(decl.name, new Export(decl, true));
  6659. break;
  6660. case VAR:
  6661. for (var i = 0; i < decl.children.length; i++)
  6662. register(decl.children[i].name, new Export(decl.children[i], true));
  6663. break;
  6664. case LET:
  6665. case CONST:
  6666. throw new Error("NYI: " + definitions.tokens[decl.type]);
  6667. case EXPORT:
  6668. for (var i = 0; i < decl.pathList.length; i++) {
  6669. var path = decl.pathList[i];
  6670. switch (path.type) {
  6671. case OBJECT_INIT:
  6672. for (var j = 0; j < path.children.length; j++) {
  6673. // init :: IDENTIFIER | PROPERTY_INIT
  6674. var init = path.children[j];
  6675. if (init.type === IDENTIFIER)
  6676. register(init.value, new Export(init, false));
  6677. else
  6678. register(init.children[0].value, new Export(init.children[1], false));
  6679. }
  6680. break;
  6681. case DOT:
  6682. register(path.children[1].value, new Export(path, false));
  6683. break;
  6684. case IDENTIFIER:
  6685. register(path.value, new Export(path, false));
  6686. break;
  6687. default:
  6688. throw new Error("unexpected export path: " + definitions.tokens[path.type]);
  6689. }
  6690. }
  6691. break;
  6692. default:
  6693. throw new Error("unexpected export decl: " + definitions.tokens[exp.type]);
  6694. }
  6695. }
  6696. /*
  6697. * Module :: (node) -> Module
  6698. *
  6699. * Static semantic representation of a module.
  6700. */
  6701. function Module(node) {
  6702. var exports = node.body.exports;
  6703. var modDefns = node.body.modDefns;
  6704. var exportedModules = new Dict();
  6705. exports.forEach(function(name, exp) {
  6706. var node = exp.node;
  6707. if (node.type === MODULE) {
  6708. exportedModules.set(name, node);
  6709. } else if (!exp.isDefinition && node.type === IDENTIFIER && modDefns.has(node.value)) {
  6710. var mod = modDefns.get(node.value);
  6711. exportedModules.set(name, mod);
  6712. }
  6713. });
  6714. this.node = node;
  6715. this.exports = exports;
  6716. this.exportedModules = exportedModules;
  6717. }
  6718. /*
  6719. * Statement :: () -> node
  6720. *
  6721. * Parses a Statement.
  6722. */
  6723. Pp.Statement = function Statement() {
  6724. var i, label, n, n2, p, c, ss, tt = this.t.get(true), tt2, x0, x2, x3;
  6725. var comments = this.t.blockComments;
  6726. // Cases for statements ending in a right curly return early, avoiding the
  6727. // common semicolon insertion magic after this switch.
  6728. switch (tt) {
  6729. case IMPORT:
  6730. if (!this.x.canImport())
  6731. this.fail("illegal context for import statement");
  6732. n = this.newNode();
  6733. n.pathList = this.ImportPathList();
  6734. this.x.parentScript.impDecls.push(n);
  6735. break;
  6736. case EXPORT:
  6737. if (!this.x.canExport())
  6738. this.fail("export statement not in module top level");
  6739. switch (this.peek()) {
  6740. case MODULE:
  6741. case FUNCTION:
  6742. case LET:
  6743. case VAR:
  6744. case CONST:
  6745. n = this.Statement();
  6746. n.blockComments = comments;
  6747. n.exported = true;
  6748. this.x.parentScript.expDecls.push(n);
  6749. registerExport(this.x.parentScript.exports, n);
  6750. return n;
  6751. }
  6752. n = this.newNode();
  6753. n.pathList = this.ExportPathList();
  6754. this.x.parentScript.expDecls.push(n);
  6755. registerExport(this.x.parentScript.exports, n);
  6756. break;
  6757. case FUNCTION:
  6758. // DECLARED_FORM extends funDecls of x, STATEMENT_FORM doesn't.
  6759. return this.FunctionDefinition(true, this.x.topLevel ? DECLARED_FORM : STATEMENT_FORM, comments);
  6760. case LEFT_CURLY:
  6761. n = this.newNode(blockInit());
  6762. x2 = this.x.update({ parentBlock: n }).pushTarget(n).nest();
  6763. this.withContext(x2, function() {
  6764. this.Statements(n);
  6765. });
  6766. this.mustMatch(RIGHT_CURLY);
  6767. return n;
  6768. case IF:
  6769. n = this.newNode();
  6770. n.condition = this.HeadExpression();
  6771. x2 = this.x.pushTarget(n).nest();
  6772. this.withContext(x2, function() {
  6773. n.thenPart = this.Statement();
  6774. n.elsePart = this.match(ELSE, true) ? this.Statement() : null;
  6775. });
  6776. return n;
  6777. case SWITCH:
  6778. // This allows CASEs after a DEFAULT, which is in the standard.
  6779. n = this.newNode({ cases: [], defaultIndex: -1 });
  6780. n.discriminant = this.HeadExpression();
  6781. x2 = this.x.pushTarget(n).nest();
  6782. this.withContext(x2, function() {
  6783. this.mustMatch(LEFT_CURLY);
  6784. while ((tt = this.t.get()) !== RIGHT_CURLY) {
  6785. switch (tt) {
  6786. case DEFAULT:
  6787. if (n.defaultIndex >= 0)
  6788. this.fail("More than one switch default");
  6789. // FALL THROUGH
  6790. case CASE:
  6791. n2 = this.newNode();
  6792. if (tt === DEFAULT)
  6793. n.defaultIndex = n.cases.length;
  6794. else
  6795. n2.caseLabel = this.Expression(COLON);
  6796. break;
  6797. default:
  6798. this.fail("Invalid switch case");
  6799. }
  6800. this.mustMatch(COLON);
  6801. n2.statements = this.newNode(blockInit());
  6802. while ((tt=this.peek(true)) !== CASE && tt !== DEFAULT &&
  6803. tt !== RIGHT_CURLY)
  6804. n2.statements.push(this.Statement());
  6805. n.cases.push(n2);
  6806. }
  6807. });
  6808. return n;
  6809. case FOR:
  6810. n = this.newNode(LOOP_INIT);
  6811. n.blockComments = comments;
  6812. if (this.match(IDENTIFIER)) {
  6813. if (this.t.token.value === "each")
  6814. n.isEach = true;
  6815. else
  6816. this.t.unget();
  6817. }
  6818. if (!this.parenFreeMode)
  6819. this.mustMatch(LEFT_PAREN);
  6820. x2 = this.x.pushTarget(n).nest();
  6821. x3 = this.x.update({ inForLoopInit: true });
  6822. n2 = null;
  6823. if ((tt = this.peek(true)) !== SEMICOLON) {
  6824. this.withContext(x3, function() {
  6825. if (tt === VAR || tt === CONST) {
  6826. this.t.get();
  6827. n2 = this.Variables();
  6828. } else if (tt === LET) {
  6829. this.t.get();
  6830. if (this.peek() === LEFT_PAREN) {
  6831. n2 = this.LetBlock(false);
  6832. } else {
  6833. // Let in for head, we need to add an implicit block
  6834. // around the rest of the for.
  6835. this.x.parentBlock = n;
  6836. n.varDecls = [];
  6837. n2 = this.Variables();
  6838. }
  6839. } else {
  6840. n2 = this.Expression();
  6841. }
  6842. });
  6843. }
  6844. if (n2 && this.match(IN)) {
  6845. n.type = FOR_IN;
  6846. this.withContext(x3, function() {
  6847. n.object = this.Expression();
  6848. if (n2.type === VAR || n2.type === LET) {
  6849. c = n2.children;
  6850. // Destructuring turns one decl into multiples, so either
  6851. // there must be only one destructuring or only one
  6852. // decl.
  6853. if (c.length !== 1 && n2.destructurings.length !== 1) {
  6854. // FIXME: this.fail ?
  6855. throw new SyntaxError("Invalid for..in left-hand side",
  6856. this.filename, n2.lineno);
  6857. }
  6858. if (n2.destructurings.length > 0) {
  6859. n.iterator = n2.destructurings[0];
  6860. } else {
  6861. n.iterator = c[0];
  6862. }
  6863. n.varDecl = n2;
  6864. } else {
  6865. if (n2.type === ARRAY_INIT || n2.type === OBJECT_INIT) {
  6866. n2.destructuredNames = this.checkDestructuring(n2);
  6867. }
  6868. n.iterator = n2;
  6869. }
  6870. });
  6871. } else {
  6872. x3.inForLoopInit = false;
  6873. n.setup = n2;
  6874. this.mustMatch(SEMICOLON);
  6875. if (n.isEach)
  6876. this.fail("Invalid for each..in loop");
  6877. this.withContext(x3, function() {
  6878. n.condition = (this.peek(true) === SEMICOLON)
  6879. ? null
  6880. : this.Expression();
  6881. this.mustMatch(SEMICOLON);
  6882. tt2 = this.peek(true);
  6883. n.update = (this.parenFreeMode
  6884. ? tt2 === LEFT_CURLY || definitions.isStatementStartCode[tt2]
  6885. : tt2 === RIGHT_PAREN)
  6886. ? null
  6887. : this.Expression();
  6888. });
  6889. }
  6890. if (!this.parenFreeMode)
  6891. this.mustMatch(RIGHT_PAREN);
  6892. this.withContext(x2, function() {
  6893. n.body = this.Statement();
  6894. });
  6895. return n;
  6896. case WHILE:
  6897. n = this.newNode({ isLoop: true });
  6898. n.blockComments = comments;
  6899. n.condition = this.HeadExpression();
  6900. x2 = this.x.pushTarget(n).nest();
  6901. this.withContext(x2, function() {
  6902. n.body = this.Statement();
  6903. });
  6904. return n;
  6905. case DO:
  6906. n = this.newNode({ isLoop: true });
  6907. n.blockComments = comments;
  6908. x2 = this.x.pushTarget(n).next();
  6909. this.withContext(x2, function() {
  6910. n.body = this.Statement();
  6911. });
  6912. this.mustMatch(WHILE);
  6913. n.condition = this.HeadExpression();
  6914. // <script language="JavaScript"> (without version hints) may need
  6915. // automatic semicolon insertion without a newline after do-while.
  6916. // See http://bugzilla.mozilla.org/show_bug.cgi?id=238945.
  6917. this.match(SEMICOLON);
  6918. return n;
  6919. case BREAK:
  6920. case CONTINUE:
  6921. n = this.newNode();
  6922. n.blockComments = comments;
  6923. // handle the |foo: break foo;| corner case
  6924. x2 = this.x.pushTarget(n);
  6925. if (this.peekOnSameLine() === IDENTIFIER) {
  6926. this.t.get();
  6927. n.label = this.t.token.value;
  6928. }
  6929. if (n.label) {
  6930. n.target = x2.labeledTargets.find(function(target) {
  6931. return target.labels.has(n.label)
  6932. });
  6933. } else if (tt === CONTINUE) {
  6934. n.target = x2.defaultLoopTarget;
  6935. } else {
  6936. n.target = x2.defaultTarget;
  6937. }
  6938. if (!n.target)
  6939. this.fail("Invalid " + ((tt === BREAK) ? "break" : "continue"));
  6940. if (!n.target.isLoop && tt === CONTINUE)
  6941. this.fail("Invalid continue");
  6942. break;
  6943. case TRY:
  6944. n = this.newNode({ catchClauses: [] });
  6945. n.blockComments = comments;
  6946. n.tryBlock = this.Block();
  6947. while (this.match(CATCH)) {
  6948. n2 = this.newNode();
  6949. p = this.MaybeLeftParen();
  6950. switch (this.t.get()) {
  6951. case LEFT_BRACKET:
  6952. case LEFT_CURLY:
  6953. // Destructured catch identifiers.
  6954. this.t.unget();
  6955. n2.varName = this.DestructuringExpression(true);
  6956. break;
  6957. case IDENTIFIER:
  6958. n2.varName = this.t.token.value;
  6959. break;
  6960. default:
  6961. this.fail("missing identifier in catch");
  6962. break;
  6963. }
  6964. if (this.match(IF)) {
  6965. if (!this.mozillaMode)
  6966. this.fail("Illegal catch guard");
  6967. if (n.catchClauses.length && !n.catchClauses.top().guard)
  6968. this.fail("Guarded catch after unguarded");
  6969. n2.guard = this.Expression();
  6970. }
  6971. this.MaybeRightParen(p);
  6972. n2.block = this.Block();
  6973. n.catchClauses.push(n2);
  6974. }
  6975. if (this.match(FINALLY))
  6976. n.finallyBlock = this.Block();
  6977. if (!n.catchClauses.length && !n.finallyBlock)
  6978. this.fail("Invalid try statement");
  6979. return n;
  6980. case CATCH:
  6981. case FINALLY:
  6982. this.fail(definitions.tokens[tt] + " without preceding try");
  6983. case THROW:
  6984. n = this.newNode();
  6985. n.exception = this.Expression();
  6986. break;
  6987. case RETURN:
  6988. n = this.ReturnOrYield();
  6989. break;
  6990. case WITH:
  6991. if (this.x.banWith())
  6992. this.fail("with statements not allowed in strict code or modules");
  6993. n = this.newNode();
  6994. n.blockComments = comments;
  6995. n.object = this.HeadExpression();
  6996. x2 = this.x.pushTarget(n).next();
  6997. this.withContext(x2, function() {
  6998. n.body = this.Statement();
  6999. });
  7000. return n;
  7001. case VAR:
  7002. case CONST:
  7003. n = this.Variables();
  7004. break;
  7005. case LET:
  7006. if (this.peek() === LEFT_PAREN) {
  7007. n = this.LetBlock(true);
  7008. return n;
  7009. }
  7010. n = this.Variables();
  7011. break;
  7012. case DEBUGGER:
  7013. n = this.newNode();
  7014. break;
  7015. case NEWLINE:
  7016. case SEMICOLON:
  7017. n = this.newNode({ type: SEMICOLON });
  7018. n.blockComments = comments;
  7019. n.expression = null;
  7020. return n;
  7021. case IDENTIFIER:
  7022. case USE:
  7023. case MODULE:
  7024. switch (this.t.token.value) {
  7025. case "use":
  7026. if (!isPragmaToken(this.peekOnSameLine())) {
  7027. this.t.unget();
  7028. break;
  7029. }
  7030. return this.newNode({ type: USE, params: this.Pragmas() });
  7031. case "module":
  7032. if (!this.x.modulesAllowed())
  7033. this.fail("module declaration not at top level");
  7034. this.x.parentScript.hasModules = true;
  7035. tt = this.peekOnSameLine();
  7036. if (tt !== IDENTIFIER && tt !== LEFT_CURLY) {
  7037. this.t.unget();
  7038. break;
  7039. }
  7040. n = this.newNode({ type: MODULE });
  7041. n.blockComments = comments;
  7042. this.mustMatch(IDENTIFIER);
  7043. label = this.t.token.value;
  7044. if (this.match(LEFT_CURLY)) {
  7045. n.name = label;
  7046. n.body = this.Script(true, false);
  7047. n.module = new Module(n);
  7048. this.mustMatch(RIGHT_CURLY);
  7049. this.x.parentScript.modDefns.set(n.name, n);
  7050. return n;
  7051. }
  7052. this.t.unget();
  7053. this.ModuleVariables(n);
  7054. return n;
  7055. default:
  7056. tt = this.peek();
  7057. // Labeled statement.
  7058. if (tt === COLON) {
  7059. label = this.t.token.value;
  7060. if (this.x.allLabels.has(label))
  7061. this.fail("Duplicate label: " + label);
  7062. this.t.get();
  7063. n = this.newNode({ type: LABEL, label: label });
  7064. n.blockComments = comments;
  7065. x2 = this.x.pushLabel(label).nest();
  7066. this.withContext(x2, function() {
  7067. n.statement = this.Statement();
  7068. });
  7069. n.target = (n.statement.type === LABEL) ? n.statement.target : n.statement;
  7070. return n;
  7071. }
  7072. // FALL THROUGH
  7073. }
  7074. // FALL THROUGH
  7075. default:
  7076. // Expression statement.
  7077. // We unget the current token to parse the expression as a whole.
  7078. n = this.newNode({ type: SEMICOLON });
  7079. this.t.unget();
  7080. n.blockComments = comments;
  7081. n.expression = this.Expression();
  7082. n.end = n.expression.end;
  7083. break;
  7084. }
  7085. n.blockComments = comments;
  7086. this.MagicalSemicolon();
  7087. return n;
  7088. }
  7089. /*
  7090. * isPragmaToken :: (number) -> boolean
  7091. */
  7092. function isPragmaToken(tt) {
  7093. switch (tt) {
  7094. case IDENTIFIER:
  7095. case STRING:
  7096. case NUMBER:
  7097. case NULL:
  7098. case TRUE:
  7099. case FALSE:
  7100. return true;
  7101. }
  7102. return false;
  7103. }
  7104. /*
  7105. * Pragmas :: () -> Array[Array[token]]
  7106. */
  7107. Pp.Pragmas = function Pragmas() {
  7108. var pragmas = [];
  7109. do {
  7110. pragmas.push(this.Pragma());
  7111. } while (this.match(COMMA));
  7112. this.MagicalSemicolon();
  7113. return pragmas;
  7114. }
  7115. /*
  7116. * Pragmas :: () -> Array[token]
  7117. */
  7118. Pp.Pragma = function Pragma() {
  7119. var items = [];
  7120. var tt;
  7121. do {
  7122. tt = this.t.get(true);
  7123. items.push(this.t.token);
  7124. } while (isPragmaToken(this.peek()));
  7125. return items;
  7126. }
  7127. /*
  7128. * MagicalSemicolon :: () -> void
  7129. */
  7130. Pp.MagicalSemicolon = function MagicalSemicolon() {
  7131. var tt;
  7132. if (this.t.lineno === this.t.token.lineno) {
  7133. tt = this.peekOnSameLine();
  7134. if (tt !== END && tt !== NEWLINE && tt !== SEMICOLON && tt !== RIGHT_CURLY)
  7135. this.fail("missing ; before statement");
  7136. }
  7137. this.match(SEMICOLON);
  7138. }
  7139. /*
  7140. * ReturnOrYield :: () -> (RETURN | YIELD) node
  7141. */
  7142. Pp.ReturnOrYield = function ReturnOrYield() {
  7143. var n, b, tt = this.t.token.type, tt2;
  7144. var parentScript = this.x.parentScript;
  7145. if (tt === RETURN) {
  7146. if (!this.x.inFunction)
  7147. this.fail("Return not in function");
  7148. } else /* if (tt === YIELD) */ {
  7149. if (!this.x.inFunction)
  7150. this.fail("Yield not in function");
  7151. parentScript.hasYield = true;
  7152. }
  7153. n = this.newNode({ value: undefined });
  7154. tt2 = (tt === RETURN) ? this.peekOnSameLine(true) : this.peek(true);
  7155. if (tt2 !== END && tt2 !== NEWLINE &&
  7156. tt2 !== SEMICOLON && tt2 !== RIGHT_CURLY
  7157. && (tt !== YIELD ||
  7158. (tt2 !== tt && tt2 !== RIGHT_BRACKET && tt2 !== RIGHT_PAREN &&
  7159. tt2 !== COLON && tt2 !== COMMA))) {
  7160. if (tt === RETURN) {
  7161. n.value = this.Expression();
  7162. parentScript.hasReturnWithValue = true;
  7163. } else {
  7164. n.value = this.AssignExpression();
  7165. }
  7166. } else if (tt === RETURN) {
  7167. parentScript.hasEmptyReturn = true;
  7168. }
  7169. return n;
  7170. }
  7171. /*
  7172. * ModuleExpression :: () -> (STRING | IDENTIFIER | DOT) node
  7173. */
  7174. Pp.ModuleExpression = function ModuleExpression() {
  7175. return this.match(STRING) ? this.newNode() : this.QualifiedPath();
  7176. }
  7177. /*
  7178. * ImportPathList :: () -> Array[DOT node]
  7179. */
  7180. Pp.ImportPathList = function ImportPathList() {
  7181. var a = [];
  7182. do {
  7183. a.push(this.ImportPath());
  7184. } while (this.match(COMMA));
  7185. return a;
  7186. }
  7187. /*
  7188. * ImportPath :: () -> DOT node
  7189. */
  7190. Pp.ImportPath = function ImportPath() {
  7191. var n = this.QualifiedPath();
  7192. if (!this.match(DOT)) {
  7193. if (n.type === IDENTIFIER)
  7194. this.fail("cannot import local variable");
  7195. return n;
  7196. }
  7197. var n2 = this.newNode();
  7198. n2.push(n);
  7199. n2.push(this.ImportSpecifierSet());
  7200. return n2;
  7201. }
  7202. /*
  7203. * ExplicitSpecifierSet :: (() -> node) -> OBJECT_INIT node
  7204. */
  7205. Pp.ExplicitSpecifierSet = function ExplicitSpecifierSet(SpecifierRHS) {
  7206. var n, n2, id, tt;
  7207. n = this.newNode({ type: OBJECT_INIT });
  7208. this.mustMatch(LEFT_CURLY);
  7209. if (!this.match(RIGHT_CURLY)) {
  7210. do {
  7211. id = this.Identifier();
  7212. if (this.match(COLON)) {
  7213. n2 = this.newNode({ type: PROPERTY_INIT });
  7214. n2.push(id);
  7215. n2.push(SpecifierRHS());
  7216. n.push(n2);
  7217. } else {
  7218. n.push(id);
  7219. }
  7220. } while (!this.match(RIGHT_CURLY) && this.mustMatch(COMMA));
  7221. }
  7222. return n;
  7223. }
  7224. /*
  7225. * ImportSpecifierSet :: () -> (IDENTIFIER | OBJECT_INIT) node
  7226. */
  7227. Pp.ImportSpecifierSet = function ImportSpecifierSet() {
  7228. var self = this;
  7229. return this.match(MUL)
  7230. ? this.newNode({ type: IDENTIFIER, name: "*" })
  7231. : ExplicitSpecifierSet(function() { return self.Identifier() });
  7232. }
  7233. /*
  7234. * Identifier :: () -> IDENTIFIER node
  7235. */
  7236. Pp.Identifier = function Identifier() {
  7237. this.mustMatch(IDENTIFIER);
  7238. return this.newNode({ type: IDENTIFIER });
  7239. }
  7240. /*
  7241. * IdentifierName :: () -> IDENTIFIER node
  7242. */
  7243. Pp.IdentifierName = function IdentifierName() {
  7244. this.mustMatch(IDENTIFIER, true);
  7245. return this.newNode({ type: IDENTIFIER });
  7246. }
  7247. /*
  7248. * QualifiedPath :: () -> (IDENTIFIER | DOT) node
  7249. */
  7250. Pp.QualifiedPath = function QualifiedPath() {
  7251. var n, n2;
  7252. n = this.Identifier();
  7253. while (this.match(DOT)) {
  7254. if (this.peek() !== IDENTIFIER) {
  7255. // Unget the '.' token, which isn't part of the QualifiedPath.
  7256. this.t.unget();
  7257. break;
  7258. }
  7259. n2 = this.newNode();
  7260. n2.push(n);
  7261. n2.push(this.Identifier());
  7262. n = n2;
  7263. }
  7264. return n;
  7265. }
  7266. /*
  7267. * ExportPath :: () -> (IDENTIFIER | DOT | OBJECT_INIT) node
  7268. */
  7269. Pp.ExportPath = function ExportPath() {
  7270. var self = this;
  7271. if (this.peek() === LEFT_CURLY)
  7272. return this.ExplicitSpecifierSet(function() { return self.QualifiedPath() });
  7273. return this.QualifiedPath();
  7274. }
  7275. /*
  7276. * ExportPathList :: () -> Array[(IDENTIFIER | DOT | OBJECT_INIT) node]
  7277. */
  7278. Pp.ExportPathList = function ExportPathList() {
  7279. var a = [];
  7280. do {
  7281. a.push(this.ExportPath());
  7282. } while (this.match(COMMA));
  7283. return a;
  7284. }
  7285. /*
  7286. * FunctionDefinition :: (boolean,
  7287. * DECLARED_FORM or EXPRESSED_FORM or STATEMENT_FORM,
  7288. * [string] or null or undefined)
  7289. * -> node
  7290. */
  7291. Pp.FunctionDefinition = function FunctionDefinition(requireName, functionForm, comments) {
  7292. var tt;
  7293. var f = this.newNode({ params: [], paramComments: [] });
  7294. if (typeof comments === "undefined")
  7295. comments = null;
  7296. f.blockComments = comments;
  7297. if (f.type !== FUNCTION)
  7298. f.type = (f.value === "get") ? GETTER : SETTER;
  7299. if (this.match(MUL))
  7300. f.isExplicitGenerator = true;
  7301. if (this.match(IDENTIFIER, false, true))
  7302. f.name = this.t.token.value;
  7303. else if (requireName)
  7304. this.fail("missing function identifier");
  7305. var inModule = this.x.inModule;
  7306. x2 = new StaticContext(null, null, inModule, true, this.x.strictMode);
  7307. this.withContext(x2, function() {
  7308. this.mustMatch(LEFT_PAREN);
  7309. if (!this.match(RIGHT_PAREN)) {
  7310. do {
  7311. tt = this.t.get();
  7312. f.paramComments.push(this.t.lastBlockComment());
  7313. switch (tt) {
  7314. case LEFT_BRACKET:
  7315. case LEFT_CURLY:
  7316. // Destructured formal parameters.
  7317. this.t.unget();
  7318. f.params.push(this.DestructuringExpression());
  7319. break;
  7320. case IDENTIFIER:
  7321. f.params.push(this.t.token.value);
  7322. break;
  7323. default:
  7324. this.fail("missing formal parameter");
  7325. }
  7326. } while (this.match(COMMA));
  7327. this.mustMatch(RIGHT_PAREN);
  7328. }
  7329. // Do we have an expression closure or a normal body?
  7330. tt = this.t.get(true);
  7331. if (tt !== LEFT_CURLY)
  7332. this.t.unget();
  7333. if (tt !== LEFT_CURLY) {
  7334. f.body = this.AssignExpression();
  7335. } else {
  7336. f.body = this.Script(inModule, true);
  7337. }
  7338. });
  7339. if (tt === LEFT_CURLY)
  7340. this.mustMatch(RIGHT_CURLY);
  7341. f.end = this.t.token.end;
  7342. f.functionForm = functionForm;
  7343. if (functionForm === DECLARED_FORM)
  7344. this.x.parentScript.funDecls.push(f);
  7345. if (this.x.inModule && !f.isExplicitGenerator && f.body.hasYield)
  7346. this.fail("yield in non-generator function");
  7347. if (f.isExplicitGenerator || f.body.hasYield)
  7348. f.body = this.newNode({ type: GENERATOR, body: f.body });
  7349. return f;
  7350. }
  7351. /*
  7352. * ModuleVariables :: (MODULE node) -> void
  7353. *
  7354. * Parses a comma-separated list of module declarations (and maybe
  7355. * initializations).
  7356. */
  7357. Pp.ModuleVariables = function ModuleVariables(n) {
  7358. var n1, n2;
  7359. do {
  7360. n1 = this.Identifier();
  7361. if (this.match(ASSIGN)) {
  7362. n2 = this.ModuleExpression();
  7363. n1.initializer = n2;
  7364. if (n2.type === STRING)
  7365. this.x.parentScript.modLoads.set(n1.value, n2.value);
  7366. else
  7367. this.x.parentScript.modAssns.set(n1.value, n1);
  7368. }
  7369. n.push(n1);
  7370. } while (this.match(COMMA));
  7371. }
  7372. /*
  7373. * Variables :: () -> node
  7374. *
  7375. * Parses a comma-separated list of var declarations (and maybe
  7376. * initializations).
  7377. */
  7378. Pp.Variables = function Variables(letBlock) {
  7379. var n, n2, ss, i, s, tt;
  7380. tt = this.t.token.type;
  7381. switch (tt) {
  7382. case VAR:
  7383. case CONST:
  7384. s = this.x.parentScript;
  7385. break;
  7386. case LET:
  7387. s = this.x.parentBlock;
  7388. break;
  7389. case LEFT_PAREN:
  7390. tt = LET;
  7391. s = letBlock;
  7392. break;
  7393. }
  7394. n = this.newNode({ type: tt, destructurings: [] });
  7395. do {
  7396. tt = this.t.get();
  7397. if (tt === LEFT_BRACKET || tt === LEFT_CURLY) {
  7398. // Need to unget to parse the full destructured expression.
  7399. this.t.unget();
  7400. var dexp = this.DestructuringExpression(true);
  7401. n2 = this.newNode({ type: IDENTIFIER,
  7402. name: dexp,
  7403. readOnly: n.type === CONST });
  7404. n.push(n2);
  7405. pushDestructuringVarDecls(n2.name.destructuredNames, s);
  7406. n.destructurings.push({ exp: dexp, decl: n2 });
  7407. if (this.x.inForLoopInit && this.peek() === IN) {
  7408. continue;
  7409. }
  7410. this.mustMatch(ASSIGN);
  7411. if (this.t.token.assignOp)
  7412. this.fail("Invalid variable initialization");
  7413. n2.blockComment = this.t.lastBlockComment();
  7414. n2.initializer = this.AssignExpression();
  7415. continue;
  7416. }
  7417. if (tt !== IDENTIFIER)
  7418. this.fail("missing variable name");
  7419. n2 = this.newNode({ type: IDENTIFIER,
  7420. name: this.t.token.value,
  7421. readOnly: n.type === CONST });
  7422. n.push(n2);
  7423. s.varDecls.push(n2);
  7424. if (this.match(ASSIGN)) {
  7425. var comment = this.t.lastBlockComment();
  7426. if (this.t.token.assignOp)
  7427. this.fail("Invalid variable initialization");
  7428. n2.initializer = this.AssignExpression();
  7429. } else {
  7430. var comment = this.t.lastBlockComment();
  7431. }
  7432. n2.blockComment = comment;
  7433. } while (this.match(COMMA));
  7434. return n;
  7435. }
  7436. /*
  7437. * LetBlock :: (boolean) -> node
  7438. *
  7439. * Does not handle let inside of for loop init.
  7440. */
  7441. Pp.LetBlock = function LetBlock(isStatement) {
  7442. var n, n2;
  7443. // t.token.type must be LET
  7444. n = this.newNode({ type: LET_BLOCK, varDecls: [] });
  7445. this.mustMatch(LEFT_PAREN);
  7446. n.variables = this.Variables(n);
  7447. this.mustMatch(RIGHT_PAREN);
  7448. if (isStatement && this.peek() !== LEFT_CURLY) {
  7449. /*
  7450. * If this is really an expression in let statement guise, then we
  7451. * need to wrap the LET_BLOCK node in a SEMICOLON node so that we pop
  7452. * the return value of the expression.
  7453. */
  7454. n2 = this.newNode({ type: SEMICOLON, expression: n });
  7455. isStatement = false;
  7456. }
  7457. if (isStatement)
  7458. n.block = this.Block();
  7459. else
  7460. n.expression = this.AssignExpression();
  7461. return n;
  7462. }
  7463. Pp.checkDestructuring = function checkDestructuring(n, simpleNamesOnly) {
  7464. if (n.type === ARRAY_COMP)
  7465. this.fail("Invalid array comprehension left-hand side");
  7466. if (n.type !== ARRAY_INIT && n.type !== OBJECT_INIT)
  7467. return;
  7468. var lhss = {};
  7469. var nn, n2, idx, sub, cc, c = n.children;
  7470. for (var i = 0, j = c.length; i < j; i++) {
  7471. if (!(nn = c[i]))
  7472. continue;
  7473. if (nn.type === PROPERTY_INIT) {
  7474. cc = nn.children;
  7475. sub = cc[1];
  7476. idx = cc[0].value;
  7477. } else if (n.type === OBJECT_INIT) {
  7478. // Do we have destructuring shorthand {foo, bar}?
  7479. sub = nn;
  7480. idx = nn.value;
  7481. } else {
  7482. sub = nn;
  7483. idx = i;
  7484. }
  7485. if (sub.type === ARRAY_INIT || sub.type === OBJECT_INIT) {
  7486. lhss[idx] = this.checkDestructuring(sub, simpleNamesOnly);
  7487. } else {
  7488. if (simpleNamesOnly && sub.type !== IDENTIFIER) {
  7489. // In declarations, lhs must be simple names
  7490. this.fail("missing name in pattern");
  7491. }
  7492. lhss[idx] = sub;
  7493. }
  7494. }
  7495. return lhss;
  7496. }
  7497. Pp.DestructuringExpression = function DestructuringExpression(simpleNamesOnly) {
  7498. var n = this.PrimaryExpression();
  7499. // Keep the list of lefthand sides for varDecls
  7500. n.destructuredNames = this.checkDestructuring(n, simpleNamesOnly);
  7501. return n;
  7502. }
  7503. Pp.GeneratorExpression = function GeneratorExpression(e) {
  7504. return this.newNode({ type: GENERATOR,
  7505. expression: e,
  7506. tail: this.ComprehensionTail() });
  7507. }
  7508. Pp.ComprehensionTail = function ComprehensionTail() {
  7509. var body, n, n2, n3, p;
  7510. // t.token.type must be FOR
  7511. body = this.newNode({ type: COMP_TAIL });
  7512. do {
  7513. // Comprehension tails are always for..in loops.
  7514. n = this.newNode({ type: FOR_IN, isLoop: true });
  7515. if (this.match(IDENTIFIER)) {
  7516. // But sometimes they're for each..in.
  7517. if (this.mozillaMode && this.t.token.value === "each")
  7518. n.isEach = true;
  7519. else
  7520. this.t.unget();
  7521. }
  7522. p = this.MaybeLeftParen();
  7523. switch(this.t.get()) {
  7524. case LEFT_BRACKET:
  7525. case LEFT_CURLY:
  7526. this.t.unget();
  7527. // Destructured left side of for in comprehension tails.
  7528. n.iterator = this.DestructuringExpression();
  7529. break;
  7530. case IDENTIFIER:
  7531. n.iterator = n3 = this.newNode({ type: IDENTIFIER });
  7532. n3.name = n3.value;
  7533. n.varDecl = n2 = this.newNode({ type: VAR });
  7534. n2.push(n3);
  7535. this.x.parentScript.varDecls.push(n3);
  7536. // Don't add to varDecls since the semantics of comprehensions is
  7537. // such that the variables are in their own function when
  7538. // desugared.
  7539. break;
  7540. default:
  7541. this.fail("missing identifier");
  7542. }
  7543. this.mustMatch(IN);
  7544. n.object = this.Expression();
  7545. this.MaybeRightParen(p);
  7546. body.push(n);
  7547. } while (this.match(FOR));
  7548. // Optional guard.
  7549. if (this.match(IF))
  7550. body.guard = this.HeadExpression();
  7551. return body;
  7552. }
  7553. Pp.HeadExpression = function HeadExpression() {
  7554. var p = this.MaybeLeftParen();
  7555. var n = this.ParenExpression();
  7556. this.MaybeRightParen(p);
  7557. if (p === END && !n.parenthesized) {
  7558. var tt = this.peek();
  7559. if (tt !== LEFT_CURLY && !definitions.isStatementStartCode[tt])
  7560. this.fail("Unparenthesized head followed by unbraced body");
  7561. }
  7562. return n;
  7563. }
  7564. Pp.ParenExpression = function ParenExpression() {
  7565. // Always accept the 'in' operator in a parenthesized expression,
  7566. // where it's unambiguous, even if we might be parsing the init of a
  7567. // for statement.
  7568. var x2 = this.x.update({
  7569. inForLoopInit: this.x.inForLoopInit && (this.t.token.type === LEFT_PAREN)
  7570. });
  7571. var n = this.withContext(x2, function() {
  7572. return this.Expression();
  7573. });
  7574. if (this.match(FOR)) {
  7575. if (n.type === YIELD && !n.parenthesized)
  7576. this.fail("Yield expression must be parenthesized");
  7577. if (n.type === COMMA && !n.parenthesized)
  7578. this.fail("Generator expression must be parenthesized");
  7579. n = this.GeneratorExpression(n);
  7580. }
  7581. return n;
  7582. }
  7583. /*
  7584. * Expression :: () -> node
  7585. *
  7586. * Top-down expression parser matched against SpiderMonkey.
  7587. */
  7588. Pp.Expression = function Expression() {
  7589. var n, n2;
  7590. n = this.AssignExpression();
  7591. if (this.match(COMMA)) {
  7592. n2 = this.newNode({ type: COMMA });
  7593. n2.push(n);
  7594. n = n2;
  7595. do {
  7596. n2 = n.children[n.children.length-1];
  7597. if (n2.type === YIELD && !n2.parenthesized)
  7598. this.fail("Yield expression must be parenthesized");
  7599. n.push(this.AssignExpression());
  7600. } while (this.match(COMMA));
  7601. }
  7602. return n;
  7603. }
  7604. Pp.AssignExpression = function AssignExpression() {
  7605. var n, lhs;
  7606. // Have to treat yield like an operand because it could be the leftmost
  7607. // operand of the expression.
  7608. if (this.match(YIELD, true))
  7609. return this.ReturnOrYield();
  7610. n = this.newNode({ type: ASSIGN });
  7611. lhs = this.ConditionalExpression();
  7612. if (!this.match(ASSIGN)) {
  7613. return lhs;
  7614. }
  7615. n.blockComment = this.t.lastBlockComment();
  7616. switch (lhs.type) {
  7617. case OBJECT_INIT:
  7618. case ARRAY_INIT:
  7619. lhs.destructuredNames = this.checkDestructuring(lhs);
  7620. // FALL THROUGH
  7621. case IDENTIFIER: case DOT: case INDEX: case CALL:
  7622. break;
  7623. default:
  7624. this.fail("Bad left-hand side of assignment");
  7625. break;
  7626. }
  7627. n.assignOp = lhs.assignOp = this.t.token.assignOp;
  7628. n.push(lhs);
  7629. n.push(this.AssignExpression());
  7630. return n;
  7631. }
  7632. Pp.ConditionalExpression = function ConditionalExpression() {
  7633. var n, n2;
  7634. n = this.OrExpression();
  7635. if (this.match(HOOK)) {
  7636. n2 = n;
  7637. n = this.newNode({ type: HOOK });
  7638. n.push(n2);
  7639. var x2 = this.x.update({ inForLoopInit: false });
  7640. this.withContext(x2, function() {
  7641. n.push(this.AssignExpression());
  7642. });
  7643. if (!this.match(COLON))
  7644. this.fail("missing : after ?");
  7645. n.push(this.AssignExpression());
  7646. }
  7647. return n;
  7648. }
  7649. Pp.OrExpression = function OrExpression() {
  7650. var n, n2;
  7651. n = this.AndExpression();
  7652. while (this.match(OR)) {
  7653. n2 = this.newNode();
  7654. n2.push(n);
  7655. n2.push(this.AndExpression());
  7656. n = n2;
  7657. }
  7658. return n;
  7659. }
  7660. Pp.AndExpression = function AndExpression() {
  7661. var n, n2;
  7662. n = this.BitwiseOrExpression();
  7663. while (this.match(AND)) {
  7664. n2 = this.newNode();
  7665. n2.push(n);
  7666. n2.push(this.BitwiseOrExpression());
  7667. n = n2;
  7668. }
  7669. return n;
  7670. }
  7671. Pp.BitwiseOrExpression = function BitwiseOrExpression() {
  7672. var n, n2;
  7673. n = this.BitwiseXorExpression();
  7674. while (this.match(BITWISE_OR)) {
  7675. n2 = this.newNode();
  7676. n2.push(n);
  7677. n2.push(this.BitwiseXorExpression());
  7678. n = n2;
  7679. }
  7680. return n;
  7681. }
  7682. Pp.BitwiseXorExpression = function BitwiseXorExpression() {
  7683. var n, n2;
  7684. n = this.BitwiseAndExpression();
  7685. while (this.match(BITWISE_XOR)) {
  7686. n2 = this.newNode();
  7687. n2.push(n);
  7688. n2.push(this.BitwiseAndExpression());
  7689. n = n2;
  7690. }
  7691. return n;
  7692. }
  7693. Pp.BitwiseAndExpression = function BitwiseAndExpression() {
  7694. var n, n2;
  7695. n = this.EqualityExpression();
  7696. while (this.match(BITWISE_AND)) {
  7697. n2 = this.newNode();
  7698. n2.push(n);
  7699. n2.push(this.EqualityExpression());
  7700. n = n2;
  7701. }
  7702. return n;
  7703. }
  7704. Pp.EqualityExpression = function EqualityExpression() {
  7705. var n, n2;
  7706. n = this.RelationalExpression();
  7707. while (this.match(EQ) || this.match(NE) ||
  7708. this.match(STRICT_EQ) || this.match(STRICT_NE)) {
  7709. n2 = this.newNode();
  7710. n2.push(n);
  7711. n2.push(this.RelationalExpression());
  7712. n = n2;
  7713. }
  7714. return n;
  7715. }
  7716. Pp.RelationalExpression = function RelationalExpression() {
  7717. var n, n2;
  7718. var x2 = this.x.update({ inForLoopInit: false });
  7719. this.withContext(x2, function() {
  7720. n = this.ShiftExpression();
  7721. while ((this.match(LT) || this.match(LE) || this.match(GE) || this.match(GT) ||
  7722. (!this.x.inForLoopInit && this.match(IN)) ||
  7723. this.match(INSTANCEOF))) {
  7724. n2 = this.newNode();
  7725. n2.push(n);
  7726. n2.push(this.ShiftExpression());
  7727. n = n2;
  7728. }
  7729. });
  7730. return n;
  7731. }
  7732. Pp.ShiftExpression = function ShiftExpression() {
  7733. var n, n2;
  7734. n = this.AddExpression();
  7735. while (this.match(LSH) || this.match(RSH) || this.match(URSH)) {
  7736. n2 = this.newNode();
  7737. n2.push(n);
  7738. n2.push(this.AddExpression());
  7739. n = n2;
  7740. }
  7741. return n;
  7742. }
  7743. Pp.AddExpression = function AddExpression() {
  7744. var n, n2;
  7745. n = this.MultiplyExpression();
  7746. while (this.match(PLUS) || this.match(MINUS)) {
  7747. n2 = this.newNode();
  7748. n2.push(n);
  7749. n2.push(this.MultiplyExpression());
  7750. n = n2;
  7751. }
  7752. return n;
  7753. }
  7754. Pp.MultiplyExpression = function MultiplyExpression() {
  7755. var n, n2;
  7756. n = this.UnaryExpression();
  7757. while (this.match(MUL) || this.match(DIV) || this.match(MOD)) {
  7758. n2 = this.newNode();
  7759. n2.push(n);
  7760. n2.push(this.UnaryExpression());
  7761. n = n2;
  7762. }
  7763. return n;
  7764. }
  7765. Pp.UnaryExpression = function UnaryExpression() {
  7766. var n, n2, tt;
  7767. switch (tt = this.t.get(true)) {
  7768. case DELETE: case VOID: case TYPEOF:
  7769. case NOT: case BITWISE_NOT: case PLUS: case MINUS:
  7770. if (tt === PLUS)
  7771. n = this.newNode({ type: UNARY_PLUS });
  7772. else if (tt === MINUS)
  7773. n = this.newNode({ type: UNARY_MINUS });
  7774. else
  7775. n = this.newNode();
  7776. n.push(this.UnaryExpression());
  7777. break;
  7778. case INCREMENT:
  7779. case DECREMENT:
  7780. // Prefix increment/decrement.
  7781. n = this.newNode();
  7782. n.push(this.MemberExpression(true));
  7783. break;
  7784. default:
  7785. this.t.unget();
  7786. n = this.MemberExpression(true);
  7787. // Don't look across a newline boundary for a postfix {in,de}crement.
  7788. if (this.t.tokens[(this.t.tokenIndex + this.t.lookahead - 1) & 3].lineno ===
  7789. this.t.lineno) {
  7790. if (this.match(INCREMENT) || this.match(DECREMENT)) {
  7791. n2 = this.newNode({ postfix: true });
  7792. n2.push(n);
  7793. n = n2;
  7794. }
  7795. }
  7796. break;
  7797. }
  7798. return n;
  7799. }
  7800. Pp.MemberExpression = function MemberExpression(allowCallSyntax) {
  7801. var n, n2, name, tt;
  7802. if (this.match(NEW)) {
  7803. n = this.newNode();
  7804. n.push(this.MemberExpression(false));
  7805. if (this.match(LEFT_PAREN)) {
  7806. n.type = NEW_WITH_ARGS;
  7807. n.push(this.ArgumentList());
  7808. }
  7809. } else {
  7810. n = this.PrimaryExpression();
  7811. }
  7812. while ((tt = this.t.get()) !== END) {
  7813. switch (tt) {
  7814. case DOT:
  7815. n2 = this.newNode();
  7816. n2.push(n);
  7817. n2.push(this.IdentifierName());
  7818. break;
  7819. case LEFT_BRACKET:
  7820. n2 = this.newNode({ type: INDEX });
  7821. n2.push(n);
  7822. n2.push(this.Expression());
  7823. this.mustMatch(RIGHT_BRACKET);
  7824. break;
  7825. case LEFT_PAREN:
  7826. if (allowCallSyntax) {
  7827. n2 = this.newNode({ type: CALL });
  7828. n2.push(n);
  7829. n2.push(this.ArgumentList());
  7830. break;
  7831. }
  7832. // FALL THROUGH
  7833. default:
  7834. this.t.unget();
  7835. return n;
  7836. }
  7837. n = n2;
  7838. }
  7839. return n;
  7840. }
  7841. Pp.ArgumentList = function ArgumentList() {
  7842. var n, n2;
  7843. n = this.newNode({ type: LIST });
  7844. if (this.match(RIGHT_PAREN, true))
  7845. return n;
  7846. do {
  7847. n2 = this.AssignExpression();
  7848. if (n2.type === YIELD && !n2.parenthesized && this.peek() === COMMA)
  7849. this.fail("Yield expression must be parenthesized");
  7850. if (this.match(FOR)) {
  7851. n2 = this.GeneratorExpression(n2);
  7852. if (n.children.length > 1 || this.peek(true) === COMMA)
  7853. this.fail("Generator expression must be parenthesized");
  7854. }
  7855. n.push(n2);
  7856. } while (this.match(COMMA));
  7857. this.mustMatch(RIGHT_PAREN);
  7858. return n;
  7859. }
  7860. Pp.PrimaryExpression = function PrimaryExpression() {
  7861. var n, n2, tt = this.t.get(true);
  7862. switch (tt) {
  7863. case FUNCTION:
  7864. n = this.FunctionDefinition(false, EXPRESSED_FORM);
  7865. break;
  7866. case LEFT_BRACKET:
  7867. n = this.newNode({ type: ARRAY_INIT });
  7868. while ((tt = this.peek(true)) !== RIGHT_BRACKET) {
  7869. if (tt === COMMA) {
  7870. this.t.get();
  7871. n.push(null);
  7872. continue;
  7873. }
  7874. n.push(this.AssignExpression());
  7875. if (tt !== COMMA && !this.match(COMMA))
  7876. break;
  7877. }
  7878. // If we matched exactly one element and got a FOR, we have an
  7879. // array comprehension.
  7880. if (n.children.length === 1 && this.match(FOR)) {
  7881. n2 = this.newNode({ type: ARRAY_COMP,
  7882. expression: n.children[0],
  7883. tail: this.ComprehensionTail() });
  7884. n = n2;
  7885. }
  7886. this.mustMatch(RIGHT_BRACKET);
  7887. break;
  7888. case LEFT_CURLY:
  7889. var id, fd;
  7890. n = this.newNode({ type: OBJECT_INIT });
  7891. object_init:
  7892. if (!this.match(RIGHT_CURLY)) {
  7893. do {
  7894. tt = this.t.get();
  7895. if ((this.t.token.value === "get" || this.t.token.value === "set") &&
  7896. this.peek() === IDENTIFIER) {
  7897. n.push(this.FunctionDefinition(true, EXPRESSED_FORM));
  7898. } else {
  7899. var comments = this.t.blockComments;
  7900. switch (tt) {
  7901. case IDENTIFIER: case NUMBER: case STRING:
  7902. id = this.newNode({ type: IDENTIFIER });
  7903. break;
  7904. case RIGHT_CURLY:
  7905. break object_init;
  7906. default:
  7907. if (this.t.token.value in definitions.keywords) {
  7908. id = this.newNode({ type: IDENTIFIER });
  7909. break;
  7910. }
  7911. this.fail("Invalid property name");
  7912. }
  7913. if (this.match(COLON)) {
  7914. n2 = this.newNode({ type: PROPERTY_INIT });
  7915. n2.push(id);
  7916. n2.push(this.AssignExpression());
  7917. n2.blockComments = comments;
  7918. n.push(n2);
  7919. } else {
  7920. // Support, e.g., |var {x, y} = o| as destructuring shorthand
  7921. // for |var {x: x, y: y} = o|, per proposed JS2/ES4 for JS1.8.
  7922. if (this.peek() !== COMMA && this.peek() !== RIGHT_CURLY)
  7923. this.fail("missing : after property");
  7924. n.push(id);
  7925. }
  7926. }
  7927. } while (this.match(COMMA));
  7928. this.mustMatch(RIGHT_CURLY);
  7929. }
  7930. break;
  7931. case LEFT_PAREN:
  7932. n = this.ParenExpression();
  7933. this.mustMatch(RIGHT_PAREN);
  7934. n.parenthesized = true;
  7935. break;
  7936. case LET:
  7937. n = this.LetBlock(false);
  7938. break;
  7939. case NULL: case THIS: case TRUE: case FALSE:
  7940. case IDENTIFIER: case NUMBER: case STRING: case REGEXP:
  7941. n = this.newNode();
  7942. break;
  7943. default:
  7944. this.fail("missing operand; found " + definitions.tokens[tt]);
  7945. break;
  7946. }
  7947. return n;
  7948. }
  7949. /*
  7950. * parse :: (source, filename, line number) -> node
  7951. */
  7952. function parse(s, f, l) {
  7953. var t = new Tokenizer(s, f, l, options.allowHTMLComments);
  7954. var p = new Parser(t);
  7955. return p.Script(false, false, true);
  7956. }
  7957. /*
  7958. * parseFunction :: (source, boolean,
  7959. * DECLARED_FORM or EXPRESSED_FORM or STATEMENT_FORM,
  7960. * filename, line number)
  7961. * -> node
  7962. */
  7963. function parseFunction(s, requireName, form, f, l) {
  7964. var t = new Tokenizer(s, f, l);
  7965. var p = new Parser(t);
  7966. p.x = new StaticContext(null, null, false, false, false);
  7967. return p.FunctionDefinition(requireName, form);
  7968. }
  7969. /*
  7970. * parseStdin :: (source, {line number}, string, (string) -> boolean) -> program node
  7971. */
  7972. function parseStdin(s, ln, prefix, isCommand) {
  7973. // the special .begin command is only recognized at the beginning
  7974. if (s.match(/^[\s]*\.begin[\s]*$/)) {
  7975. ++ln.value;
  7976. return parseMultiline(ln, prefix);
  7977. }
  7978. // commands at the beginning are treated as the entire input
  7979. if (isCommand(s.trim()))
  7980. s = "";
  7981. for (;;) {
  7982. try {
  7983. var t = new Tokenizer(s, "stdin", ln.value, false);
  7984. var p = new Parser(t);
  7985. var n = p.Script(false, false);
  7986. ln.value = t.lineno;
  7987. return n;
  7988. } catch (e) {
  7989. if (!p.unexpectedEOF)
  7990. throw e;
  7991. // commands in the middle are not treated as part of the input
  7992. var more;
  7993. do {
  7994. if (prefix)
  7995. putstr(prefix);
  7996. more = readline();
  7997. if (!more)
  7998. throw e;
  7999. } while (isCommand(more.trim()));
  8000. s += "\n" + more;
  8001. }
  8002. }
  8003. }
  8004. /*
  8005. * parseMultiline :: ({line number}, string | null) -> program node
  8006. */
  8007. function parseMultiline(ln, prefix) {
  8008. var s = "";
  8009. for (;;) {
  8010. if (prefix)
  8011. putstr(prefix);
  8012. var more = readline();
  8013. if (more === null)
  8014. return null;
  8015. // the only command recognized in multiline mode is .end
  8016. if (more.match(/^[\s]*\.end[\s]*$/))
  8017. break;
  8018. s += "\n" + more;
  8019. }
  8020. var t = new Tokenizer(s, "stdin", ln.value, false);
  8021. var p = new Parser(t);
  8022. var n = p.Script(false, false);
  8023. ln.value = t.lineno;
  8024. return n;
  8025. }
  8026. exports.parse = parse;
  8027. exports.parseStdin = parseStdin;
  8028. exports.parseFunction = parseFunction;
  8029. exports.Node = Node;
  8030. exports.DECLARED_FORM = DECLARED_FORM;
  8031. exports.EXPRESSED_FORM = EXPRESSED_FORM;
  8032. exports.STATEMENT_FORM = STATEMENT_FORM;
  8033. exports.Tokenizer = Tokenizer;
  8034. exports.Parser = Parser;
  8035. exports.Module = Module;
  8036. exports.Export = Export;
  8037. });
  8038. /* ***** BEGIN LICENSE BLOCK *****
  8039. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  8040. *
  8041. * The contents of this file are subject to the Mozilla Public License Version
  8042. * 1.1 (the "License"); you may not use this file except in compliance with
  8043. * the License. You may obtain a copy of the License at
  8044. * http://www.mozilla.org/MPL/
  8045. *
  8046. * Software distributed under the License is distributed on an "AS IS" basis,
  8047. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  8048. * for the specific language governing rights and limitations under the
  8049. * License.
  8050. *
  8051. * The Original Code is the Narcissus JavaScript engine.
  8052. *
  8053. * The Initial Developer of the Original Code is
  8054. * Brendan Eich <brendan@mozilla.org>.
  8055. * Portions created by the Initial Developer are Copyright (C) 2004
  8056. * the Initial Developer. All Rights Reserved.
  8057. *
  8058. * Contributor(s):
  8059. * Tom Austin <taustin@ucsc.edu>
  8060. * Brendan Eich <brendan@mozilla.org>
  8061. * Shu-Yu Guo <shu@rfrn.org>
  8062. * Stephan Herhut <stephan.a.herhut@intel.com>
  8063. * Dave Herman <dherman@mozilla.com>
  8064. * Dimitris Vardoulakis <dimvar@ccs.neu.edu>
  8065. * Patrick Walton <pcwalton@mozilla.com>
  8066. *
  8067. * Alternatively, the contents of this file may be used under the terms of
  8068. * either the GNU General Public License Version 2 or later (the "GPL"), or
  8069. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  8070. * in which case the provisions of the GPL or the LGPL are applicable instead
  8071. * of those above. If you wish to allow use of your version of this file only
  8072. * under the terms of either the GPL or the LGPL, and not to allow others to
  8073. * use your version of this file under the terms of the MPL, indicate your
  8074. * decision by deleting the provisions above and replace them with the notice
  8075. * and other provisions required by the GPL or the LGPL. If you do not delete
  8076. * the provisions above, a recipient may use your version of this file under
  8077. * the terms of any one of the MPL, the GPL or the LGPL.
  8078. *
  8079. * ***** END LICENSE BLOCK ***** */
  8080. /*
  8081. * Narcissus - JS implemented in JS.
  8082. *
  8083. * Lexical scanner.
  8084. */
  8085. define('ace/narcissus/lexer', ['require', 'exports', 'module' , 'ace/narcissus/definitions'], function(require, exports, module) {
  8086. var definitions = require('./definitions');
  8087. // Set constants in the local scope.
  8088. eval(definitions.consts);
  8089. // Build up a trie of operator tokens.
  8090. var opTokens = {};
  8091. for (var op in definitions.opTypeNames) {
  8092. if (op === '\n' || op === '.')
  8093. continue;
  8094. var node = opTokens;
  8095. for (var i = 0; i < op.length; i++) {
  8096. var ch = op[i];
  8097. if (!(ch in node))
  8098. node[ch] = {};
  8099. node = node[ch];
  8100. node.op = op;
  8101. }
  8102. }
  8103. /*
  8104. * Since JavaScript provides no convenient way to determine if a
  8105. * character is in a particular Unicode category, we use
  8106. * metacircularity to accomplish this (oh yeaaaah!)
  8107. */
  8108. function isValidIdentifierChar(ch, first) {
  8109. // check directly for ASCII
  8110. if (ch <= "\u007F") {
  8111. if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch === '$' || ch === '_' ||
  8112. (!first && (ch >= '0' && ch <= '9'))) {
  8113. return true;
  8114. }
  8115. return false;
  8116. }
  8117. // create an object to test this in
  8118. var x = {};
  8119. x["x"+ch] = true;
  8120. x[ch] = true;
  8121. // then use eval to determine if it's a valid character
  8122. var valid = false;
  8123. try {
  8124. valid = (Function("x", "return (x." + (first?"":"x") + ch + ");")(x) === true);
  8125. } catch (ex) {}
  8126. return valid;
  8127. }
  8128. function isIdentifier(str) {
  8129. if (typeof str !== "string")
  8130. return false;
  8131. if (str.length === 0)
  8132. return false;
  8133. if (!isValidIdentifierChar(str[0], true))
  8134. return false;
  8135. for (var i = 1; i < str.length; i++) {
  8136. if (!isValidIdentifierChar(str[i], false))
  8137. return false;
  8138. }
  8139. return true;
  8140. }
  8141. /*
  8142. * Tokenizer :: (source, filename, line number, boolean) -> Tokenizer
  8143. */
  8144. function Tokenizer(s, f, l, allowHTMLComments) {
  8145. this.cursor = 0;
  8146. this.source = String(s);
  8147. this.tokens = [];
  8148. this.tokenIndex = 0;
  8149. this.lookahead = 0;
  8150. this.scanNewlines = false;
  8151. this.filename = f || "";
  8152. this.lineno = l || 1;
  8153. this.allowHTMLComments = allowHTMLComments;
  8154. this.blockComments = null;
  8155. }
  8156. Tokenizer.prototype = {
  8157. get done() {
  8158. // We need to set scanOperand to true here because the first thing
  8159. // might be a regexp.
  8160. return this.peek(true) === END;
  8161. },
  8162. get token() {
  8163. return this.tokens[this.tokenIndex];
  8164. },
  8165. match: function (tt, scanOperand, keywordIsName) {
  8166. return this.get(scanOperand, keywordIsName) === tt || this.unget();
  8167. },
  8168. mustMatch: function (tt, keywordIsName) {
  8169. if (!this.match(tt, false, keywordIsName)) {
  8170. throw this.newSyntaxError("Missing " +
  8171. definitions.tokens[tt].toLowerCase());
  8172. }
  8173. return this.token;
  8174. },
  8175. peek: function (scanOperand) {
  8176. var tt, next;
  8177. if (this.lookahead) {
  8178. next = this.tokens[(this.tokenIndex + this.lookahead) & 3];
  8179. tt = (this.scanNewlines && next.lineno !== this.lineno)
  8180. ? NEWLINE
  8181. : next.type;
  8182. } else {
  8183. tt = this.get(scanOperand);
  8184. this.unget();
  8185. }
  8186. return tt;
  8187. },
  8188. peekOnSameLine: function (scanOperand) {
  8189. this.scanNewlines = true;
  8190. var tt = this.peek(scanOperand);
  8191. this.scanNewlines = false;
  8192. return tt;
  8193. },
  8194. lastBlockComment: function() {
  8195. var length = this.blockComments.length;
  8196. return length ? this.blockComments[length - 1] : null;
  8197. },
  8198. // Eat comments and whitespace.
  8199. skip: function () {
  8200. var input = this.source;
  8201. this.blockComments = [];
  8202. for (;;) {
  8203. var ch = input[this.cursor++];
  8204. var next = input[this.cursor];
  8205. // handle \r, \r\n and (always preferable) \n
  8206. if (ch === '\r') {
  8207. // if the next character is \n, we don't care about this at all
  8208. if (next === '\n') continue;
  8209. // otherwise, we want to consider this as a newline
  8210. ch = '\n';
  8211. }
  8212. if (ch === '\n' && !this.scanNewlines) {
  8213. this.lineno++;
  8214. } else if (ch === '/' && next === '*') {
  8215. var commentStart = ++this.cursor;
  8216. for (;;) {
  8217. ch = input[this.cursor++];
  8218. if (ch === undefined)
  8219. throw this.newSyntaxError("Unterminated comment");
  8220. if (ch === '*') {
  8221. next = input[this.cursor];
  8222. if (next === '/') {
  8223. var commentEnd = this.cursor - 1;
  8224. this.cursor++;
  8225. break;
  8226. }
  8227. } else if (ch === '\n') {
  8228. this.lineno++;
  8229. }
  8230. }
  8231. this.blockComments.push(input.substring(commentStart, commentEnd));
  8232. } else if ((ch === '/' && next === '/') ||
  8233. (this.allowHTMLComments && ch === '<' && next === '!' &&
  8234. input[this.cursor + 1] === '-' && input[this.cursor + 2] === '-' &&
  8235. (this.cursor += 2))) {
  8236. this.cursor++;
  8237. for (;;) {
  8238. ch = input[this.cursor++];
  8239. next = input[this.cursor];
  8240. if (ch === undefined)
  8241. return;
  8242. if (ch === '\r') {
  8243. // check for \r\n
  8244. if (next !== '\n') ch = '\n';
  8245. }
  8246. if (ch === '\n') {
  8247. if (this.scanNewlines) {
  8248. this.cursor--;
  8249. } else {
  8250. this.lineno++;
  8251. }
  8252. break;
  8253. }
  8254. }
  8255. } else if (!(ch in definitions.whitespace)) {
  8256. this.cursor--;
  8257. return;
  8258. }
  8259. }
  8260. },
  8261. // Lex the exponential part of a number, if present. Return true iff an
  8262. // exponential part was found.
  8263. lexExponent: function() {
  8264. var input = this.source;
  8265. var next = input[this.cursor];
  8266. if (next === 'e' || next === 'E') {
  8267. this.cursor++;
  8268. ch = input[this.cursor++];
  8269. if (ch === '+' || ch === '-')
  8270. ch = input[this.cursor++];
  8271. if (ch < '0' || ch > '9')
  8272. throw this.newSyntaxError("Missing exponent");
  8273. do {
  8274. ch = input[this.cursor++];
  8275. } while (ch >= '0' && ch <= '9');
  8276. this.cursor--;
  8277. return true;
  8278. }
  8279. return false;
  8280. },
  8281. lexZeroNumber: function (ch) {
  8282. var token = this.token, input = this.source;
  8283. token.type = NUMBER;
  8284. ch = input[this.cursor++];
  8285. if (ch === '.') {
  8286. do {
  8287. ch = input[this.cursor++];
  8288. } while (ch >= '0' && ch <= '9');
  8289. this.cursor--;
  8290. this.lexExponent();
  8291. token.value = parseFloat(
  8292. input.substring(token.start, this.cursor));
  8293. } else if (ch === 'x' || ch === 'X') {
  8294. do {
  8295. ch = input[this.cursor++];
  8296. } while ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') ||
  8297. (ch >= 'A' && ch <= 'F'));
  8298. this.cursor--;
  8299. token.value = parseInt(input.substring(token.start, this.cursor));
  8300. } else if (ch >= '0' && ch <= '7') {
  8301. do {
  8302. ch = input[this.cursor++];
  8303. } while (ch >= '0' && ch <= '7');
  8304. this.cursor--;
  8305. token.value = parseInt(input.substring(token.start, this.cursor));
  8306. } else {
  8307. this.cursor--;
  8308. this.lexExponent(); // 0E1, &c.
  8309. token.value = 0;
  8310. }
  8311. },
  8312. lexNumber: function (ch) {
  8313. var token = this.token, input = this.source;
  8314. token.type = NUMBER;
  8315. var floating = false;
  8316. do {
  8317. ch = input[this.cursor++];
  8318. if (ch === '.' && !floating) {
  8319. floating = true;
  8320. ch = input[this.cursor++];
  8321. }
  8322. } while (ch >= '0' && ch <= '9');
  8323. this.cursor--;
  8324. var exponent = this.lexExponent();
  8325. floating = floating || exponent;
  8326. var str = input.substring(token.start, this.cursor);
  8327. token.value = floating ? parseFloat(str) : parseInt(str);
  8328. },
  8329. lexDot: function (ch) {
  8330. var token = this.token, input = this.source;
  8331. var next = input[this.cursor];
  8332. if (next >= '0' && next <= '9') {
  8333. do {
  8334. ch = input[this.cursor++];
  8335. } while (ch >= '0' && ch <= '9');
  8336. this.cursor--;
  8337. this.lexExponent();
  8338. token.type = NUMBER;
  8339. token.value = parseFloat(
  8340. input.substring(token.start, this.cursor));
  8341. } else {
  8342. token.type = DOT;
  8343. token.assignOp = null;
  8344. token.value = '.';
  8345. }
  8346. },
  8347. lexString: function (ch) {
  8348. var token = this.token, input = this.source;
  8349. token.type = STRING;
  8350. var hasEscapes = false;
  8351. var delim = ch;
  8352. if (input.length <= this.cursor)
  8353. throw this.newSyntaxError("Unterminated string literal");
  8354. while ((ch = input[this.cursor++]) !== delim) {
  8355. if (ch == '\n' || ch == '\r')
  8356. throw this.newSyntaxError("Unterminated string literal");
  8357. if (this.cursor == input.length)
  8358. throw this.newSyntaxError("Unterminated string literal");
  8359. if (ch === '\\') {
  8360. hasEscapes = true;
  8361. if (++this.cursor == input.length)
  8362. throw this.newSyntaxError("Unterminated string literal");
  8363. }
  8364. }
  8365. token.value = hasEscapes
  8366. ? eval(input.substring(token.start, this.cursor))
  8367. : input.substring(token.start + 1, this.cursor - 1);
  8368. },
  8369. lexRegExp: function (ch) {
  8370. var token = this.token, input = this.source;
  8371. token.type = REGEXP;
  8372. do {
  8373. ch = input[this.cursor++];
  8374. if (ch === '\\') {
  8375. this.cursor++;
  8376. } else if (ch === '[') {
  8377. do {
  8378. if (ch === undefined)
  8379. throw this.newSyntaxError("Unterminated character class");
  8380. if (ch === '\\')
  8381. this.cursor++;
  8382. ch = input[this.cursor++];
  8383. } while (ch !== ']');
  8384. } else if (ch === undefined) {
  8385. throw this.newSyntaxError("Unterminated regex");
  8386. }
  8387. } while (ch !== '/');
  8388. do {
  8389. ch = input[this.cursor++];
  8390. } while (ch >= 'a' && ch <= 'z');
  8391. this.cursor--;
  8392. token.value = eval(input.substring(token.start, this.cursor));
  8393. },
  8394. lexOp: function (ch) {
  8395. var token = this.token, input = this.source;
  8396. // A bit ugly, but it seems wasteful to write a trie lookup routine
  8397. // for only 3 characters...
  8398. var node = opTokens[ch];
  8399. var next = input[this.cursor];
  8400. if (next in node) {
  8401. node = node[next];
  8402. this.cursor++;
  8403. next = input[this.cursor];
  8404. if (next in node) {
  8405. node = node[next];
  8406. this.cursor++;
  8407. next = input[this.cursor];
  8408. }
  8409. }
  8410. var op = node.op;
  8411. if (definitions.assignOps[op] && input[this.cursor] === '=') {
  8412. this.cursor++;
  8413. token.type = ASSIGN;
  8414. token.assignOp = definitions.tokenIds[definitions.opTypeNames[op]];
  8415. op += '=';
  8416. } else {
  8417. token.type = definitions.tokenIds[definitions.opTypeNames[op]];
  8418. token.assignOp = null;
  8419. }
  8420. token.value = op;
  8421. },
  8422. // FIXME: Unicode escape sequences
  8423. lexIdent: function (ch, keywordIsName) {
  8424. var token = this.token;
  8425. var id = ch;
  8426. while ((ch = this.getValidIdentifierChar(false)) !== null) {
  8427. id += ch;
  8428. }
  8429. token.type = IDENTIFIER;
  8430. token.value = id;
  8431. if (keywordIsName)
  8432. return;
  8433. var kw;
  8434. if (this.parser.mozillaMode) {
  8435. kw = definitions.mozillaKeywords[id];
  8436. if (kw) {
  8437. token.type = kw;
  8438. return;
  8439. }
  8440. }
  8441. if (this.parser.x.strictMode) {
  8442. kw = definitions.strictKeywords[id];
  8443. if (kw) {
  8444. token.type = kw;
  8445. return;
  8446. }
  8447. }
  8448. kw = definitions.keywords[id];
  8449. if (kw)
  8450. token.type = kw;
  8451. },
  8452. /*
  8453. * Tokenizer.get :: ([boolean[, boolean]]) -> token type
  8454. *
  8455. * Consume input *only* if there is no lookahead.
  8456. * Dispatch to the appropriate lexing function depending on the input.
  8457. */
  8458. get: function (scanOperand, keywordIsName) {
  8459. var token;
  8460. while (this.lookahead) {
  8461. --this.lookahead;
  8462. this.tokenIndex = (this.tokenIndex + 1) & 3;
  8463. token = this.tokens[this.tokenIndex];
  8464. if (token.type !== NEWLINE || this.scanNewlines)
  8465. return token.type;
  8466. }
  8467. this.skip();
  8468. this.tokenIndex = (this.tokenIndex + 1) & 3;
  8469. token = this.tokens[this.tokenIndex];
  8470. if (!token)
  8471. this.tokens[this.tokenIndex] = token = {};
  8472. var input = this.source;
  8473. if (this.cursor >= input.length)
  8474. return token.type = END;
  8475. token.start = this.cursor;
  8476. token.lineno = this.lineno;
  8477. var ich = this.getValidIdentifierChar(true);
  8478. var ch = (ich === null) ? input[this.cursor++] : null;
  8479. if (ich !== null) {
  8480. this.lexIdent(ich, keywordIsName);
  8481. } else if (scanOperand && ch === '/') {
  8482. this.lexRegExp(ch);
  8483. } else if (ch in opTokens) {
  8484. this.lexOp(ch);
  8485. } else if (ch === '.') {
  8486. this.lexDot(ch);
  8487. } else if (ch >= '1' && ch <= '9') {
  8488. this.lexNumber(ch);
  8489. } else if (ch === '0') {
  8490. this.lexZeroNumber(ch);
  8491. } else if (ch === '"' || ch === "'") {
  8492. this.lexString(ch);
  8493. } else if (this.scanNewlines && (ch === '\n' || ch === '\r')) {
  8494. // if this was a \r, look for \r\n
  8495. if (ch === '\r' && input[this.cursor] === '\n') this.cursor++;
  8496. token.type = NEWLINE;
  8497. token.value = '\n';
  8498. this.lineno++;
  8499. } else {
  8500. throw this.newSyntaxError("Illegal token");
  8501. }
  8502. token.end = this.cursor;
  8503. return token.type;
  8504. },
  8505. /*
  8506. * Tokenizer.unget :: void -> undefined
  8507. *
  8508. * Match depends on unget returning undefined.
  8509. */
  8510. unget: function () {
  8511. if (++this.lookahead === 4) throw "PANIC: too much lookahead!";
  8512. this.tokenIndex = (this.tokenIndex - 1) & 3;
  8513. },
  8514. newSyntaxError: function (m) {
  8515. m = (this.filename ? this.filename + ":" : "") + this.lineno + ": " + m;
  8516. var e = new SyntaxError(m, this.filename, this.lineno);
  8517. e.source = this.source;
  8518. e.cursor = this.lookahead
  8519. ? this.tokens[(this.tokenIndex + this.lookahead) & 3].start
  8520. : this.cursor;
  8521. return e;
  8522. },
  8523. /* Gets a single valid identifier char from the input stream, or null
  8524. * if there is none.
  8525. */
  8526. getValidIdentifierChar: function(first) {
  8527. var input = this.source;
  8528. if (this.cursor >= input.length) return null;
  8529. var ch = input[this.cursor];
  8530. // first check for \u escapes
  8531. if (ch === '\\' && input[this.cursor+1] === 'u') {
  8532. // get the character value
  8533. try {
  8534. ch = String.fromCharCode(parseInt(
  8535. input.substring(this.cursor + 2, this.cursor + 6),
  8536. 16));
  8537. } catch (ex) {
  8538. return null;
  8539. }
  8540. this.cursor += 5;
  8541. }
  8542. var valid = isValidIdentifierChar(ch, first);
  8543. if (valid) this.cursor++;
  8544. return (valid ? ch : null);
  8545. },
  8546. };
  8547. exports.isIdentifier = isIdentifier;
  8548. exports.Tokenizer = Tokenizer;
  8549. });
  8550. /* ***** BEGIN LICENSE BLOCK *****
  8551. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  8552. *
  8553. * The contents of this file are subject to the Mozilla Public License Version
  8554. * 1.1 (the "License"); you may not use this file except in compliance with
  8555. * the License. You may obtain a copy of the License at
  8556. * http://www.mozilla.org/MPL/
  8557. *
  8558. * Software distributed under the License is distributed on an "AS IS" basis,
  8559. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  8560. * for the specific language governing rights and limitations under the
  8561. * License.
  8562. *
  8563. * The Original Code is the Narcissus JavaScript engine.
  8564. *
  8565. * The Initial Developer of the Original Code is
  8566. * Brendan Eich <brendan@mozilla.org>.
  8567. * Portions created by the Initial Developer are Copyright (C) 2004
  8568. * the Initial Developer. All Rights Reserved.
  8569. *
  8570. * Contributor(s):
  8571. * Tom Austin <taustin@ucsc.edu>
  8572. * Brendan Eich <brendan@mozilla.org>
  8573. * Shu-Yu Guo <shu@rfrn.org>
  8574. * Dave Herman <dherman@mozilla.com>
  8575. * Dimitris Vardoulakis <dimvar@ccs.neu.edu>
  8576. * Patrick Walton <pcwalton@mozilla.com>
  8577. *
  8578. * Alternatively, the contents of this file may be used under the terms of
  8579. * either the GNU General Public License Version 2 or later (the "GPL"), or
  8580. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  8581. * in which case the provisions of the GPL or the LGPL are applicable instead
  8582. * of those above. If you wish to allow use of your version of this file only
  8583. * under the terms of either the GPL or the LGPL, and not to allow others to
  8584. * use your version of this file under the terms of the MPL, indicate your
  8585. * decision by deleting the provisions above and replace them with the notice
  8586. * and other provisions required by the GPL or the LGPL. If you do not delete
  8587. * the provisions above, a recipient may use your version of this file under
  8588. * the terms of any one of the MPL, the GPL or the LGPL.
  8589. *
  8590. * ***** END LICENSE BLOCK ***** */
  8591. /*
  8592. * Narcissus - JS implemented in JS.
  8593. *
  8594. * Well-known constants and lookup tables. Many consts are generated from the
  8595. * tokens table via eval to minimize redundancy, so consumers must be compiled
  8596. * separately to take advantage of the simple switch-case constant propagation
  8597. * done by SpiderMonkey.
  8598. */
  8599. define('ace/narcissus/definitions', ['require', 'exports', 'module' ], function(require, exports, module) {
  8600. var tokens = [
  8601. // End of source.
  8602. "END",
  8603. // Operators and punctuators. Some pair-wise order matters, e.g. (+, -)
  8604. // and (UNARY_PLUS, UNARY_MINUS).
  8605. "\n", ";",
  8606. ",",
  8607. "=",
  8608. "?", ":", "CONDITIONAL",
  8609. "||",
  8610. "&&",
  8611. "|",
  8612. "^",
  8613. "&",
  8614. "==", "!=", "===", "!==",
  8615. "<", "<=", ">=", ">",
  8616. "<<", ">>", ">>>",
  8617. "+", "-",
  8618. "*", "/", "%",
  8619. "!", "~", "UNARY_PLUS", "UNARY_MINUS",
  8620. "++", "--",
  8621. ".",
  8622. "[", "]",
  8623. "{", "}",
  8624. "(", ")",
  8625. // Nonterminal tree node type codes.
  8626. "SCRIPT", "BLOCK", "LABEL", "FOR_IN", "CALL", "NEW_WITH_ARGS", "INDEX",
  8627. "ARRAY_INIT", "OBJECT_INIT", "PROPERTY_INIT", "GETTER", "SETTER",
  8628. "GROUP", "LIST", "LET_BLOCK", "ARRAY_COMP", "GENERATOR", "COMP_TAIL",
  8629. // Contextual keywords.
  8630. "IMPLEMENTS", "INTERFACE", "LET", "MODULE", "PACKAGE", "PRIVATE",
  8631. "PROTECTED", "PUBLIC", "STATIC", "USE", "YIELD",
  8632. // Terminals.
  8633. "IDENTIFIER", "NUMBER", "STRING", "REGEXP",
  8634. // Keywords.
  8635. "break",
  8636. "case", "catch", "const", "continue",
  8637. "debugger", "default", "delete", "do",
  8638. "else", "export",
  8639. "false", "finally", "for", "function",
  8640. "if", "import", "in", "instanceof",
  8641. "new", "null",
  8642. "return",
  8643. "switch",
  8644. "this", "throw", "true", "try", "typeof",
  8645. "var", "void",
  8646. "while", "with",
  8647. ];
  8648. var strictKeywords = {
  8649. __proto__: null,
  8650. "implements": true,
  8651. "interface": true,
  8652. "let": true,
  8653. //"module": true,
  8654. "package": true,
  8655. "private": true,
  8656. "protected": true,
  8657. "public": true,
  8658. "static": true,
  8659. "use": true,
  8660. "yield": true
  8661. };
  8662. var statementStartTokens = [
  8663. "break",
  8664. "const", "continue",
  8665. "debugger", "do",
  8666. "for",
  8667. "if",
  8668. "let",
  8669. "return",
  8670. "switch",
  8671. "throw", "try",
  8672. "var",
  8673. "yield",
  8674. "while", "with",
  8675. ];
  8676. // Whitespace characters (see ECMA-262 7.2)
  8677. var whitespaceChars = [
  8678. // normal whitespace:
  8679. "\u0009", "\u000B", "\u000C", "\u0020", "\u00A0", "\uFEFF",
  8680. // high-Unicode whitespace:
  8681. "\u1680", "\u180E",
  8682. "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", "\u2005", "\u2006",
  8683. "\u2007", "\u2008", "\u2009", "\u200A",
  8684. "\u202F", "\u205F", "\u3000"
  8685. ];
  8686. var whitespace = {};
  8687. for (var i = 0; i < whitespaceChars.length; i++) {
  8688. whitespace[whitespaceChars[i]] = true;
  8689. }
  8690. // Operator and punctuator mapping from token to tree node type name.
  8691. // NB: because the lexer doesn't backtrack, all token prefixes must themselves
  8692. // be valid tokens (e.g. !== is acceptable because its prefixes are the valid
  8693. // tokens != and !).
  8694. var opTypeNames = {
  8695. '\n': "NEWLINE",
  8696. ';': "SEMICOLON",
  8697. ',': "COMMA",
  8698. '?': "HOOK",
  8699. ':': "COLON",
  8700. '||': "OR",
  8701. '&&': "AND",
  8702. '|': "BITWISE_OR",
  8703. '^': "BITWISE_XOR",
  8704. '&': "BITWISE_AND",
  8705. '===': "STRICT_EQ",
  8706. '==': "EQ",
  8707. '=': "ASSIGN",
  8708. '!==': "STRICT_NE",
  8709. '!=': "NE",
  8710. '<<': "LSH",
  8711. '<=': "LE",
  8712. '<': "LT",
  8713. '>>>': "URSH",
  8714. '>>': "RSH",
  8715. '>=': "GE",
  8716. '>': "GT",
  8717. '++': "INCREMENT",
  8718. '--': "DECREMENT",
  8719. '+': "PLUS",
  8720. '-': "MINUS",
  8721. '*': "MUL",
  8722. '/': "DIV",
  8723. '%': "MOD",
  8724. '!': "NOT",
  8725. '~': "BITWISE_NOT",
  8726. '.': "DOT",
  8727. '[': "LEFT_BRACKET",
  8728. ']': "RIGHT_BRACKET",
  8729. '{': "LEFT_CURLY",
  8730. '}': "RIGHT_CURLY",
  8731. '(': "LEFT_PAREN",
  8732. ')': "RIGHT_PAREN"
  8733. };
  8734. // Hash of keyword identifier to tokens index. NB: we must null __proto__ to
  8735. // avoid toString, etc. namespace pollution.
  8736. var keywords = {__proto__: null};
  8737. var mozillaKeywords = {__proto__: null};
  8738. // Define const END, etc., based on the token names. Also map name to index.
  8739. var tokenIds = {};
  8740. var hostSupportsEvalConst = (function() {
  8741. try {
  8742. return eval("(function(s) { eval(s); return x })('const x = true;')");
  8743. } catch (e) {
  8744. return false;
  8745. }
  8746. })();
  8747. // Building up a string to be eval'd in different contexts.
  8748. var consts = hostSupportsEvalConst ? "const " : "var ";
  8749. for (var i = 0, j = tokens.length; i < j; i++) {
  8750. if (i > 0)
  8751. consts += ", ";
  8752. var t = tokens[i];
  8753. var name;
  8754. if (/^[a-z]/.test(t)) {
  8755. name = t.toUpperCase();
  8756. if (name === "LET" || name === "YIELD")
  8757. mozillaKeywords[name] = i;
  8758. if (strictKeywords[name])
  8759. strictKeywords[name] = i;
  8760. keywords[t] = i;
  8761. } else {
  8762. name = (/^\W/.test(t) ? opTypeNames[t] : t);
  8763. }
  8764. consts += name + " = " + i;
  8765. tokenIds[name] = i;
  8766. tokens[t] = i;
  8767. }
  8768. consts += ";";
  8769. var isStatementStartCode = {__proto__: null};
  8770. for (i = 0, j = statementStartTokens.length; i < j; i++)
  8771. isStatementStartCode[keywords[statementStartTokens[i]]] = true;
  8772. // Map assignment operators to their indexes in the tokens array.
  8773. var assignOps = ['|', '^', '&', '<<', '>>', '>>>', '+', '-', '*', '/', '%'];
  8774. for (i = 0, j = assignOps.length; i < j; i++) {
  8775. t = assignOps[i];
  8776. assignOps[t] = tokens[t];
  8777. }
  8778. function defineGetter(obj, prop, fn, dontDelete, dontEnum) {
  8779. Object.defineProperty(obj, prop,
  8780. { get: fn, configurable: !dontDelete, enumerable: !dontEnum });
  8781. }
  8782. function defineGetterSetter(obj, prop, getter, setter, dontDelete, dontEnum) {
  8783. Object.defineProperty(obj, prop, {
  8784. get: getter,
  8785. set: setter,
  8786. configurable: !dontDelete,
  8787. enumerable: !dontEnum
  8788. });
  8789. }
  8790. function defineMemoGetter(obj, prop, fn, dontDelete, dontEnum) {
  8791. Object.defineProperty(obj, prop, {
  8792. get: function() {
  8793. var val = fn();
  8794. defineProperty(obj, prop, val, dontDelete, true, dontEnum);
  8795. return val;
  8796. },
  8797. configurable: true,
  8798. enumerable: !dontEnum
  8799. });
  8800. }
  8801. function defineProperty(obj, prop, val, dontDelete, readOnly, dontEnum) {
  8802. Object.defineProperty(obj, prop,
  8803. { value: val, writable: !readOnly, configurable: !dontDelete,
  8804. enumerable: !dontEnum });
  8805. }
  8806. // Returns true if fn is a native function. (Note: SpiderMonkey specific.)
  8807. function isNativeCode(fn) {
  8808. // Relies on the toString method to identify native code.
  8809. return ((typeof fn) === "function") && fn.toString().match(/\[native code\]/);
  8810. }
  8811. var Fpapply = Function.prototype.apply;
  8812. function apply(f, o, a) {
  8813. return Fpapply.call(f, [o].concat(a));
  8814. }
  8815. var applyNew;
  8816. // ES5's bind is a simpler way to implement applyNew
  8817. if (Function.prototype.bind) {
  8818. applyNew = function applyNew(f, a) {
  8819. return new (f.bind.apply(f, [,].concat(Array.prototype.slice.call(a))))();
  8820. };
  8821. } else {
  8822. applyNew = function applyNew(f, a) {
  8823. switch (a.length) {
  8824. case 0:
  8825. return new f();
  8826. case 1:
  8827. return new f(a[0]);
  8828. case 2:
  8829. return new f(a[0], a[1]);
  8830. case 3:
  8831. return new f(a[0], a[1], a[2]);
  8832. default:
  8833. var argStr = "a[0]";
  8834. for (var i = 1, n = a.length; i < n; i++)
  8835. argStr += ",a[" + i + "]";
  8836. return eval("new f(" + argStr + ")");
  8837. }
  8838. };
  8839. }
  8840. function getPropertyDescriptor(obj, name) {
  8841. while (obj) {
  8842. if (({}).hasOwnProperty.call(obj, name))
  8843. return Object.getOwnPropertyDescriptor(obj, name);
  8844. obj = Object.getPrototypeOf(obj);
  8845. }
  8846. }
  8847. function getPropertyNames(obj) {
  8848. var table = Object.create(null, {});
  8849. while (obj) {
  8850. var names = Object.getOwnPropertyNames(obj);
  8851. for (var i = 0, n = names.length; i < n; i++)
  8852. table[names[i]] = true;
  8853. obj = Object.getPrototypeOf(obj);
  8854. }
  8855. return Object.keys(table);
  8856. }
  8857. function getOwnProperties(obj) {
  8858. var map = {};
  8859. for (var name in Object.getOwnPropertyNames(obj))
  8860. map[name] = Object.getOwnPropertyDescriptor(obj, name);
  8861. return map;
  8862. }
  8863. function blacklistHandler(target, blacklist) {
  8864. var mask = Object.create(null, {});
  8865. var redirect = Dict.create(blacklist).mapObject(function(name) { return mask; });
  8866. return mixinHandler(redirect, target);
  8867. }
  8868. function whitelistHandler(target, whitelist) {
  8869. var catchall = Object.create(null, {});
  8870. var redirect = Dict.create(whitelist).mapObject(function(name) { return target; });
  8871. return mixinHandler(redirect, catchall);
  8872. }
  8873. /*
  8874. * Mixin proxies break the single-inheritance model of prototypes, so
  8875. * the handler treats all properties as own-properties:
  8876. *
  8877. * X
  8878. * |
  8879. * +------------+------------+
  8880. * | O |
  8881. * | | |
  8882. * | O O O |
  8883. * | | | | |
  8884. * | O O O O |
  8885. * | | | | | |
  8886. * | O O O O O |
  8887. * | | | | | | |
  8888. * +-(*)--(w)--(x)--(y)--(z)-+
  8889. */
  8890. function mixinHandler(redirect, catchall) {
  8891. function targetFor(name) {
  8892. return hasOwn(redirect, name) ? redirect[name] : catchall;
  8893. }
  8894. function getMuxPropertyDescriptor(name) {
  8895. var desc = getPropertyDescriptor(targetFor(name), name);
  8896. if (desc)
  8897. desc.configurable = true;
  8898. return desc;
  8899. }
  8900. function getMuxPropertyNames() {
  8901. var names1 = Object.getOwnPropertyNames(redirect).filter(function(name) {
  8902. return name in redirect[name];
  8903. });
  8904. var names2 = getPropertyNames(catchall).filter(function(name) {
  8905. return !hasOwn(redirect, name);
  8906. });
  8907. return names1.concat(names2);
  8908. }
  8909. function enumerateMux() {
  8910. var result = Object.getOwnPropertyNames(redirect).filter(function(name) {
  8911. return name in redirect[name];
  8912. });
  8913. for (name in catchall) {
  8914. if (!hasOwn(redirect, name))
  8915. result.push(name);
  8916. };
  8917. return result;
  8918. }
  8919. function hasMux(name) {
  8920. return name in targetFor(name);
  8921. }
  8922. return {
  8923. getOwnPropertyDescriptor: getMuxPropertyDescriptor,
  8924. getPropertyDescriptor: getMuxPropertyDescriptor,
  8925. getOwnPropertyNames: getMuxPropertyNames,
  8926. defineProperty: function(name, desc) {
  8927. Object.defineProperty(targetFor(name), name, desc);
  8928. },
  8929. "delete": function(name) {
  8930. var target = targetFor(name);
  8931. return delete target[name];
  8932. },
  8933. // FIXME: ha ha ha
  8934. fix: function() { },
  8935. has: hasMux,
  8936. hasOwn: hasMux,
  8937. get: function(receiver, name) {
  8938. var target = targetFor(name);
  8939. return target[name];
  8940. },
  8941. set: function(receiver, name, val) {
  8942. var target = targetFor(name);
  8943. target[name] = val;
  8944. return true;
  8945. },
  8946. enumerate: enumerateMux,
  8947. keys: enumerateMux
  8948. };
  8949. }
  8950. function makePassthruHandler(obj) {
  8951. // Handler copied from
  8952. // http://wiki.ecmascript.org/doku.php?id=harmony:proxies&s=proxy%20object#examplea_no-op_forwarding_proxy
  8953. return {
  8954. getOwnPropertyDescriptor: function(name) {
  8955. var desc = Object.getOwnPropertyDescriptor(obj, name);
  8956. // a trapping proxy's properties must always be configurable
  8957. desc.configurable = true;
  8958. return desc;
  8959. },
  8960. getPropertyDescriptor: function(name) {
  8961. var desc = getPropertyDescriptor(obj, name);
  8962. // a trapping proxy's properties must always be configurable
  8963. desc.configurable = true;
  8964. return desc;
  8965. },
  8966. getOwnPropertyNames: function() {
  8967. return Object.getOwnPropertyNames(obj);
  8968. },
  8969. defineProperty: function(name, desc) {
  8970. Object.defineProperty(obj, name, desc);
  8971. },
  8972. "delete": function(name) { return delete obj[name]; },
  8973. fix: function() {
  8974. if (Object.isFrozen(obj)) {
  8975. return getOwnProperties(obj);
  8976. }
  8977. // As long as obj is not frozen, the proxy won't allow itself to be fixed.
  8978. return undefined; // will cause a TypeError to be thrown
  8979. },
  8980. has: function(name) { return name in obj; },
  8981. hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); },
  8982. get: function(receiver, name) { return obj[name]; },
  8983. // bad behavior when set fails in non-strict mode
  8984. set: function(receiver, name, val) { obj[name] = val; return true; },
  8985. enumerate: function() {
  8986. var result = [];
  8987. for (name in obj) { result.push(name); };
  8988. return result;
  8989. },
  8990. keys: function() { return Object.keys(obj); }
  8991. };
  8992. }
  8993. var hasOwnProperty = ({}).hasOwnProperty;
  8994. function hasOwn(obj, name) {
  8995. return hasOwnProperty.call(obj, name);
  8996. }
  8997. function Dict(table, size) {
  8998. this.table = table || Object.create(null, {});
  8999. this.size = size || 0;
  9000. }
  9001. Dict.create = function(table) {
  9002. var init = Object.create(null, {});
  9003. var size = 0;
  9004. var names = Object.getOwnPropertyNames(table);
  9005. for (var i = 0, n = names.length; i < n; i++) {
  9006. var name = names[i];
  9007. init[name] = table[name];
  9008. size++;
  9009. }
  9010. return new Dict(init, size);
  9011. };
  9012. Dict.prototype = {
  9013. has: function(x) { return hasOwnProperty.call(this.table, x); },
  9014. set: function(x, v) {
  9015. if (!hasOwnProperty.call(this.table, x))
  9016. this.size++;
  9017. this.table[x] = v;
  9018. },
  9019. get: function(x) { return this.table[x]; },
  9020. getDef: function(x, thunk) {
  9021. if (!hasOwnProperty.call(this.table, x)) {
  9022. this.size++;
  9023. this.table[x] = thunk();
  9024. }
  9025. return this.table[x];
  9026. },
  9027. forEach: function(f) {
  9028. var table = this.table;
  9029. for (var key in table)
  9030. f.call(this, key, table[key]);
  9031. },
  9032. map: function(f) {
  9033. var table1 = this.table;
  9034. var table2 = Object.create(null, {});
  9035. this.forEach(function(key, val) {
  9036. table2[key] = f.call(this, val, key);
  9037. });
  9038. return new Dict(table2, this.size);
  9039. },
  9040. mapObject: function(f) {
  9041. var table1 = this.table;
  9042. var table2 = Object.create(null, {});
  9043. this.forEach(function(key, val) {
  9044. table2[key] = f.call(this, val, key);
  9045. });
  9046. return table2;
  9047. },
  9048. toObject: function() {
  9049. return this.mapObject(function(val) { return val; });
  9050. },
  9051. choose: function() {
  9052. return Object.getOwnPropertyNames(this.table)[0];
  9053. },
  9054. remove: function(x) {
  9055. if (hasOwnProperty.call(this.table, x)) {
  9056. this.size--;
  9057. delete this.table[x];
  9058. }
  9059. },
  9060. copy: function() {
  9061. var table = Object.create(null, {});
  9062. for (var key in this.table)
  9063. table[key] = this.table[key];
  9064. return new Dict(table, this.size);
  9065. },
  9066. keys: function() {
  9067. return Object.keys(this.table);
  9068. },
  9069. toString: function() { return "[object Dict]" }
  9070. };
  9071. var _WeakMap = typeof WeakMap === "function" ? WeakMap : (function() {
  9072. // shim for ES6 WeakMap with poor asymptotics
  9073. function WeakMap(array) {
  9074. this.array = array || [];
  9075. }
  9076. function searchMap(map, key, found, notFound) {
  9077. var a = map.array;
  9078. for (var i = 0, n = a.length; i < n; i++) {
  9079. var pair = a[i];
  9080. if (pair.key === key)
  9081. return found(pair, i);
  9082. }
  9083. return notFound();
  9084. }
  9085. WeakMap.prototype = {
  9086. has: function(x) {
  9087. return searchMap(this, x, function() { return true }, function() { return false });
  9088. },
  9089. set: function(x, v) {
  9090. var a = this.array;
  9091. searchMap(this, x,
  9092. function(pair) { pair.value = v },
  9093. function() { a.push({ key: x, value: v }) });
  9094. },
  9095. get: function(x) {
  9096. return searchMap(this, x,
  9097. function(pair) { return pair.value },
  9098. function() { return null });
  9099. },
  9100. "delete": function(x) {
  9101. var a = this.array;
  9102. searchMap(this, x,
  9103. function(pair, i) { a.splice(i, 1) },
  9104. function() { });
  9105. },
  9106. toString: function() { return "[object WeakMap]" }
  9107. };
  9108. return WeakMap;
  9109. })();
  9110. // non-destructive stack
  9111. function Stack(elts) {
  9112. this.elts = elts || null;
  9113. }
  9114. Stack.prototype = {
  9115. push: function(x) {
  9116. return new Stack({ top: x, rest: this.elts });
  9117. },
  9118. top: function() {
  9119. if (!this.elts)
  9120. throw new Error("empty stack");
  9121. return this.elts.top;
  9122. },
  9123. isEmpty: function() {
  9124. return this.top === null;
  9125. },
  9126. find: function(test) {
  9127. for (var elts = this.elts; elts; elts = elts.rest) {
  9128. if (test(elts.top))
  9129. return elts.top;
  9130. }
  9131. return null;
  9132. },
  9133. has: function(x) {
  9134. return Boolean(this.find(function(elt) { return elt === x }));
  9135. },
  9136. forEach: function(f) {
  9137. for (var elts = this.elts; elts; elts = elts.rest) {
  9138. f(elts.top);
  9139. }
  9140. }
  9141. };
  9142. if (!Array.prototype.copy) {
  9143. defineProperty(Array.prototype, "copy",
  9144. function() {
  9145. var result = [];
  9146. for (var i = 0, n = this.length; i < n; i++)
  9147. result[i] = this[i];
  9148. return result;
  9149. }, false, false, true);
  9150. }
  9151. if (!Array.prototype.top) {
  9152. defineProperty(Array.prototype, "top",
  9153. function() {
  9154. return this.length && this[this.length-1];
  9155. }, false, false, true);
  9156. }
  9157. exports.tokens = tokens;
  9158. exports.whitespace = whitespace;
  9159. exports.opTypeNames = opTypeNames;
  9160. exports.keywords = keywords;
  9161. exports.mozillaKeywords = mozillaKeywords;
  9162. exports.strictKeywords = strictKeywords;
  9163. exports.isStatementStartCode = isStatementStartCode;
  9164. exports.tokenIds = tokenIds;
  9165. exports.consts = consts;
  9166. exports.assignOps = assignOps;
  9167. exports.defineGetter = defineGetter;
  9168. exports.defineGetterSetter = defineGetterSetter;
  9169. exports.defineMemoGetter = defineMemoGetter;
  9170. exports.defineProperty = defineProperty;
  9171. exports.isNativeCode = isNativeCode;
  9172. exports.apply = apply;
  9173. exports.applyNew = applyNew;
  9174. exports.mixinHandler = mixinHandler;
  9175. exports.whitelistHandler = whitelistHandler;
  9176. exports.blacklistHandler = blacklistHandler;
  9177. exports.makePassthruHandler = makePassthruHandler;
  9178. exports.Dict = Dict;
  9179. exports.WeakMap = _WeakMap;
  9180. exports.Stack = Stack;
  9181. });
  9182. /* ***** BEGIN LICENSE BLOCK *****
  9183. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  9184. *
  9185. * The contents of this file are subject to the Mozilla Public License Version
  9186. * 1.1 (the "License"); you may not use this file except in compliance with
  9187. * the License. You may obtain a copy of the License at
  9188. * http://www.mozilla.org/MPL/
  9189. *
  9190. * Software distributed under the License is distributed on an "AS IS" basis,
  9191. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  9192. * for the specific language governing rights and limitations under the
  9193. * License.
  9194. *
  9195. * The Original Code is the Narcissus JavaScript engine.
  9196. *
  9197. * The Initial Developer of the Original Code is
  9198. * Brendan Eich <brendan@mozilla.org>.
  9199. * Portions created by the Initial Developer are Copyright (C) 2004
  9200. * the Initial Developer. All Rights Reserved.
  9201. *
  9202. * Contributor(s):
  9203. * Tom Austin <taustin@ucsc.edu>
  9204. * Brendan Eich <brendan@mozilla.org>
  9205. * Shu-Yu Guo <shu@rfrn.org>
  9206. * Dave Herman <dherman@mozilla.com>
  9207. * Dimitris Vardoulakis <dimvar@ccs.neu.edu>
  9208. * Patrick Walton <pcwalton@mozilla.com>
  9209. *
  9210. * Alternatively, the contents of this file may be used under the terms of
  9211. * either the GNU General Public License Version 2 or later (the "GPL"), or
  9212. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  9213. * in which case the provisions of the GPL or the LGPL are applicable instead
  9214. * of those above. If you wish to allow use of your version of this file only
  9215. * under the terms of either the GPL or the LGPL, and not to allow others to
  9216. * use your version of this file under the terms of the MPL, indicate your
  9217. * decision by deleting the provisions above and replace them with the notice
  9218. * and other provisions required by the GPL or the LGPL. If you do not delete
  9219. * the provisions above, a recipient may use your version of this file under
  9220. * the terms of any one of the MPL, the GPL or the LGPL.
  9221. *
  9222. * ***** END LICENSE BLOCK ***** */
  9223. define('ace/narcissus/options', ['require', 'exports', 'module' ], function(require, exports, module) {
  9224. // Global variables to hide from the interpreter
  9225. exports.hiddenHostGlobals = { Narcissus: true };
  9226. // Desugar SpiderMonkey language extensions?
  9227. exports.desugarExtensions = false;
  9228. // Allow HTML comments?
  9229. exports.allowHTMLComments = false;
  9230. // Allow non-standard Mozilla extensions?
  9231. exports.mozillaMode = true;
  9232. // Allow experimental paren-free mode?
  9233. exports.parenFreeMode = false;
  9234. });